Een variant van variabele grootte maken en invullen.

Status
Niet open voor verdere reacties.

dadio25

Gebruiker
Lid geworden
17 mrt 2009
Berichten
39
Hallo,

Ik heb een listview met maximaal 16 items elk item heeft daarnaast ook 3 subitems.

De bedoeling is dat iemand een item kan selecteren. Dan wordt de listview.enabled op false gezet.

Dan wordt er in een textbox een waarde ingevuld. Nu is het de bedoeling dat deze waarde die vanalles kan bevatten van strings tot numerieke getallen in een variant() gezet wordt.

Deze variant is gedeclareerd als Dim myvariant(16) as Variant. Aangezien er maximaal maar 16 items zijn.

Nu is het mijn bedoeling dat elke keer als er een item geselecteerd wordt en er wordt een nieuwe waarde voor gegeven dat deze waarde in myvariant komt.

Ik probeer het met een index die elke keer opgehoogd wordt bij elk nieuw item om dit te doen, maar dan is het subscript buiten bereik. Hoe kan ik zorgen dat ik een variant van variabele grootte kan maken en invullen met waardes??

groeten DaDio25
 
Dit ding
Code:
dim naam() as string
is een array die je met
Code:
Redim naam(lngX)
groter of kleiner maakt. Redim maakt je array gelijk leeg. Als je dat niet wilt gebruik je
Code:
redim preserve naam(lngX)

Enjoy!
 
hallo,

bedankt voor je antwoord, maar ik ga toch voor een statisch array. Ik zal nooit meer dan 16 items gebruiken.

Maar ik heb een probleem met het gewoon vullen mijn array. Ik gebruik daar een index voor. de array begint overigens wel bij 1. Dat is een vereiste voor mijn programma.

Code:
Dim writeindex As Integer
Dim writevalues(16) As Variant
Dim value As Long

Deze gebruik ik om een array te kunnen maken. en met odnerstaande code wil ik hem proberen te gaan vullen. Mar dan krijg ik dat het subscript buiten bereik is.

Code:
writevalues(writeindex) = value

Van wat ik zo'n beetje heb kunnen vinden op internet zou dit gewoon moeten kunnen aangezien het variant datatype alle data types volgens mij zo'n beetje aan kan.
 
je writeindex moet wel eerst gevuld worden voor je hem gebruikt.
value is van het type long. een variant kan deze waarde wel aan maar wellicht kan je die eerst omzetten naar het type variant:
Code:
writevalues(writeindex) = cvar(value)
HTH:D
 
Hallo,

Bedankt voor je antwoord op het moment dat je het typte probeerde ik het zelf en dat lukte idd, maar ik zet de waarde gelijk in een variant...

Nu ben ik verder gegaan met het programma en loop weer tegen iets aan. Ik zit te denken aan iets van een datatype incompatabiliteit. Maar heb wat documentatie voor wat ik probeer en daar zetten ze een long in een variabele array van type variant. Terwijl ik een variant in een variant array probeer te zetten heel simpel gezegd.

Ik probeer een waarde in een variabele array van type variant te plaatsen. Deze waarde komt van een textbox en heb ik via
Code:
writevalue = textbox1.value
volgens documentatie dat ik heb moet dat op de volgende manier

Code:
Values(ServerIndex) = writevalue

waarin values als volgt is gedeclareerd:
Code:
Dim Values() As Variant

Nu krijg ik hier de foutmelding dat het subscript buiten bereik is. De variabele writevalue heb ik gedeclareerd als Variant.

Volgens documentatie doe ik het op een goede manier, maar vba vind van niet. Dus waar ga ik de mist in?

Edit:

Heb nu twee problemen het eerste is het bovenstaande dat de subscript buiten bereik valt.

Een ander is misschien wat makkelijker op te lossen, maar kom er eventjes niet aan uit.

Ik maak gebruik van alle data type gewoon door elkaar. Ik kan erachter komen welke datatype ik nodig heb. Dan vul ik een waarde in in een textbox.

Daarna maar ik een select case op basis van de integer waarde van de datatype.

Dan is het de bedoeling dat de waarde omgezet wordt naar het juiste datatype. en dan moet deze in een array van het datatype variant gezet worden. de grootte van dit array staat vast.

Nu wil ik graag weten wat is volgens jullie de beste manier om die conversie te doen en hoe zet ik de waarde het beste in het array. Dit array wordt later gebruikt om een ander array ook van het type variant te vullen alleen dit array heeft een variabele grootte.

Ik hoop dat iemand mij wat ideeen kan geven. Ik ben wel bezig met dingen zoals Cint enzo alleen ik las ergens dat dit gebruikt wordt om van een variant naar een ander data type te gaan en niet andersom.

groeten dadio25
 
Laatst bewerkt:
Ik zou geen gebruik maken van de naam VALUES omdat het een gereserveerd woord is in Excel maar ook in SQL.

Ik weet het niet zeker maar volgens mij past je Variant array zich aan aan de eerste waarde die wordt ingelezen. Als het een long is dan wordt je hele array van het type long.

als je de hele functie eens post dan kan ik een gerichter antwoord geven want je code schept veel vragen op die voorkomen hadden kunnen worden als ik de hele functie zie.

HTH:D
 
Hallo,

bedankt voor het antwoorden:D.

Het probleem is dat dat Values() ook gebruikt wordt waar ik mee bezig ben en dat is schrijven naar een OPC server. Of het lezen van een OPC server. Dan is Values() de waardes van de items die gelezen dienen te worden.

En aangezien in de server veel verschillende datatypen gebruikt wordt zoals: string,DWord Date, Boolean, Long, Float, Short, Word etc.

Moet ik zorgen dat de waarden uit de textbo x de juiste waarde heeft om geschreven te worden anders krijg ik daar een foutmelding op. Maar hier is de Code :D
Code voor schrijven naar de OPC server met de regel die die subscript fout geeft
Code:
Private Sub Writeitem_Click()

On Error GoTo ShowOPCWriteItemError

Dim NumItems As Long
Dim ServerIndex As Long
Dim ServerHandles(16) As Long
Dim Values() As Variant
Dim Errors() As Long
Dim ServerTransactionID As Long
Dim writevalue As Variant

NumItems = writeitems

For ServerIndex = 1 To NumItems

ServerHandles(ServerIndex) = WriteItemServerHandles(ServerIndex)

writevalue = writevalues(ServerIndex)
Values(ServerIndex) = writevalue <---- Deze regel

Next ServerIndex

MyOPCGroup.AsyncWrite NumItems, ServerHandles, Values, Errors, ClientTransactionID, ServerTransactionID

ShowOPCWriteItemError:
    Call DisplayOPC_COM_ErrorValue("OPC Write Items", Err.Number)
SkipOPCWriteItemError:
ClientTransactionID = ClientTransactionID + 1
Erase writevalues
writeitems = 0
ServerIndex = 0
End Sub

Code om de juiste item te vinden van de server zodat het datatype bekend wordt..
Code:
ElseIf MsgBox("Wilt u een of meer items schrijven?", vbOKCancel, "Active state") = vbOK Then
If writeitems <= 16 Then

index = Itemview.SelectedItem.index
writeitems = writeitems + 1
writeindex = writeindex + 1
WriteItemServerHandles(writeitems) = ItemServerHandles(index)
Set Writeitem = MyOPCItems.GetOPCItem(WriteItemServerHandles(writeitems))
currentvalue = Writeitem.CanonicalDataType
Itemview.Enabled = False
Else: MsgBox "U kunt maar 16 items proberen te schrijven druk op de write item knop", vbOKOnly

End If
End If

En de code om de waarde van de textbox om te zetten.
Code:
Private Sub Addwritevalue_Click()

Dim writeomzetstring As String

If writevalue.Text = "" Then
MsgBox "U moet een waarde in de tekstbox invoegen", vbOKOnly
Else
Select Case currentvalue
Case 2
value = CInt(writevalue.value)
Case 3
value = CLng(writevalue.value)
Case 4
value = CSng(writevalue.value)
Case 5
value = CDbl(writevalue.value)
Case 7
value = CDate(writevalue.Text)
Case 8
value = writevalue.Text
Case 11
value = CBool(writevalue.Text)
Case 16
value = writevalue.Text
Case 17
value = CByte(writevalue.value)
Case 18
value = CInt(writevalue.value)
Case 19
value = CLng(writevalue.value)
Case 8192
value = writevalue.value
End Select
writevalues(writeindex) = value
End If

Itemview.Enabled = True
End Sub

Ik hoop dat je er een beetje wijs uitkunt.

Groeten DaDio25
 
Ik zie dat je veelvuldig gebruik maakt van globale variabelen.

Code:
writevalue = writevalues(ServerIndex)
Values(ServerIndex) = writevalue <---- Deze regel
Ik kan niet zien wat voor type wrtievalues is, maar deze code zou kunnen werken:
Code:
Values(ServerIndex) = CVar(Nz(writevalues(ServerIndex),""))
Enjoy!
 
Hallo

bedankt voor je antwoord ik ga het gelijk proberen.

Ik gebruik veel globale variabelen, omdat ik gemerkt heb dat ik in veel van mijn subs die variabelen ook weer nodig heb.

Maar writevalues is van het type variant.
Code:
Dim writevalues(1 To 16) As Variant

groeten dadio25
 
Je kan aan procedures en functies parameters meegeven waardoor je applicatie veel minder overhead geeft en eenvoudiger is te debuggen. Zo hou je functionaliteiten gescheiden en beter leesbaar.
Het default click event is zoals je al gebruikt.
Code:
Private Sub Addwritevalue_Click()
'
' heleboel code hier
'
End sub
Je kan ook verwijzen naar een andere functie zodat die op meerdere in je code is aan te roepen.
Code:
Private Sub Addwritevalue_Click()
'
    Dim intRetVal as integer

    ProcedureAanroep gintNaamID ' Globale variabele van het type int.

    intRetVal = FunctieAanroep(gintNaamID)
'
End sub

Private Sub ProcedureAanroep(intNaamID as integer)

End sub

'In aparte module:
Public Sub FunctieAanroep(intNaamID as integer) as integer

end sub
Ik gebruik nooit veel globale variabelen.

Als je de hongaarse variabelen notatie gebruikt dan zie je ook wat voor type je variabele is.

HTH:D
 
Hallo goedemorgen :D,

Hmmm daar heb je ook wel gelijk in, maar ik had hiervoor nog nooit voor een opc client geprogrammeerd dus wist totaal niet wat er allemaal zou komen. En sommige dingen komen idd best vaak terug zoals het maken van bepaalde arrays. Maar heb wel een bepaalde functie om te browsen in mijn server om dit weer tegeven als een treeview en deze zou een stuk beter kunnen heb niet bepaald met recursieve constructies gewerkt alhoewel ik wel geleerd heb om dit te kunnen. ik zal dat gedeelte eens posten dan snap je wat ik bedoel. Misschien zie jij gelijk hoe ik dat het beste had kunnen doen. Ik was allang blij dat ik het helemaal werkende had gekregen. Vond het gebruik maken van de treeview best pittig eigenlijk.

Code:
Private Sub Down()
    Dim childnode As Node
    Dim currentp As String
    Dim counter As Long
    
    OPCMyBrowser.showbranches
    counter = OPCMyBrowser.Count
   
    For Each vName In OPCMyBrowser
    childstring = SrvName & "." & vName
    Set childnode = Serverview.Nodes.Add(SrvName, tvwChild, childstring, "" & vName)
        OPCMyBrowser.movedown (vName)
        OPCMyBrowser.showbranches
        counter = OPCMyBrowser.Count
        OPCMyBrowser.showleafs
        counter = OPCMyBrowser.Count

        If counter > 0 Then
        Call showleafs(SrvName, childstring, vName)
        Else
        Call showbranches(SrvName, childstring, vName)
        End If
        OPCMyBrowser.MoveUp
    Next vName
    currentp = OPCMyBrowser.CurrentPosition
    Error.Text = currentp
End Sub

Private Sub showleafs(SrvName As String, childstring As String, vName As Variant)
 OPCMyBrowser.showleafs
 Dim babystring As String
 Dim childnode As Node
        For Each vName In OPCMyBrowser
        babystring = childstring & "." & vName
          Set childnode = Serverview.Nodes.Add(childstring, tvwChild, babystring, "" & vName)
        Next vName

End Sub

Private Sub showbranches(SrvName As String, childstring As String, vName As Variant)
    Dim counter As Long
    Dim counter2 As Long
    Dim childnode As Node
    OPCMyBrowser.showbranches
        For Each vName In OPCMyBrowser
        babystring = childstring & "." & vName
          Set childnode = Serverview.Nodes.Add(childstring, tvwChild, babystring, "" & vName)
        OPCMyBrowser.movedown (vName)
        OPCMyBrowser.showbranches
        counter2 = OPCMyBrowser.Count

        OPCMyBrowser.showleafs
        counter = OPCMyBrowser.Count

        If (counter > 0 And counter2 = 0) Then
        Call showleafs2(SrvName, babystring, vName)
        ElseIf (counter = 0 And counter2 > 0) Then
        Call showbranches2(SrvName, babystring, vName)
        ElseIf (counter > 0 And counter2 > 0) Then
        Call showbranches3(SrvName, babystring, vName)
        End If
        OPCMyBrowser.MoveUp
        Next vName
     
End Sub

Private Sub showbranches2(SrvName As String, babystring As String, vName As Variant)
        
    Dim counter2 As Long
    Dim ministring As String
    Dim childnode As Node
    Dim counter As Long
    
    OPCMyBrowser.showbranches
    For Each vName In OPCMyBrowser
        ministring = babystring & "." & vName
        Set childnode = Serverview.Nodes.Add(babystring, tvwChild, ministring, "" & vName)
        OPCMyBrowser.movedown (vName)
        OPCMyBrowser.showbranches
        counter = OPCMyBrowser.Count
        OPCMyBrowser.showleafs
        counter2 = OPCMyBrowser.Count

            If counter > 0 & counter2 > 0 Then
            
                Call showbranches3(SrvName, babystring, vName)

            End If
        Next vName
End Sub


Private Sub showleafs2(SrvName As String, babystring As String, vName As Variant)
 Dim ministring As String
 OPCMyBrowser.showleafs
    Dim childnode As Node
        For Each vName In OPCMyBrowser
            ministring = babystring & "." & vName
            Set childnode = Serverview.Nodes.Add(babystring, tvwChild, ministring, "" & vName)
        Next vName
End Sub


Private Sub showbranches3(SrvName As String, babystring As String, vName As Variant)
    Dim counter2 As Long
    Dim childnode As Node
    Dim counter As Long
    Dim ministring As String
   OPCMyBrowser.showbranches
    For Each vName In OPCMyBrowser
        ministring = babystring & "." & vName
        Set childnode = Serverview.Nodes.Add(babystring, tvwChild, ministring, "" & vName)
        OPCMyBrowser.movedown (vName)
        OPCMyBrowser.showbranches
        OPCMyBrowser.showleafs
        counter = OPCMyBrowser.Count
    If counter > 0 Then
        Call showleafs3(SrvName, ministring, vName)
        
    End If
        OPCMyBrowser.MoveUp
        OPCMyBrowser.showbranches
        counter2 = OPCMyBrowser.Count

    Next vName
        OPCMyBrowser.showleafs
        counter2 = OPCMyBrowser.Count

    If (counter2 > 0) Then
        Call showleafs2(SrvName, babystring, vName)
    End If
End Sub


Private Sub showleafs3(SrvName As String, ministring As String, vName As Variant)
 Dim laatstestring As String
 OPCMyBrowser.showleafs
 Dim childnode As Node
        For Each vName In OPCMyBrowser
            laatstestring = ministring & "." & vName
            Set childnode = Serverview.Nodes.Add(ministring, tvwChild, laatstestring, "" & vName)
        Next vName

End Sub

Het is nogal een grote lap met code. Maar wat dit doet is. Ik heb mijn node met mijn server root al in de treeview gezet. Nu gebruik ik een browser object om achter de branches(mappen) van de server te komen. Deze geef ik weer met showbranches. Dan met de for loop pak ik de eerste naam deze gaat naar de treeview. Dan ga ik een level naar beneden in deze branche(map) Ik kijk of er branches(mappen) of leafs(bestanden) zijn of beide. Bij branches weet ik dat ik daar weer de eerste van moet weergeven en een level naar beneden totdat ik bij een branch kom waarin alleen leafs staan. Deze geef ik allemaal weer met een for loop. Als ik daarmee klaar ben ga ik een level omhoog. en pak ik de volgende branch en doe ik precies hetzelfde totdat ik klaar ben.

Maar zie je wat ik bedoel?

groeten DaDio25
 
Hallo,

Ik heb een vraagje?

Is het mogelijk om numerieke data en string data in hetzelfde array van het type variant te krijgen??

groeten dadio25
 
Hmmm ik krijg een 424 foutmelding op de volgende regel ik heb de help door genomen, maar ik snap niet waarom dit is. Misschien nog een verwijzing ofzo hiernaar toe??

Code:
writevalue.Enabled = False
 
De code voor je treeview ziet er netjes uit. Mooi modulair opgebouwd. Ook zonder hongaarse notatie:D
Mijn code voor de treeview ziet er natuurlijk anders uit. Ik geloof dat het het enige stukje code is wat je nooit zomaar kan overnemen. Er moet altijd aan gesleuteld worden.
Hallo,

Ik heb een vraagje?

Is het mogelijk om numerieke data en string data in hetzelfde array van het type variant te krijgen??

groeten dadio25
Je kan een user defined type maken. Hieronder een die ik zelf gebruik
Code:
Public Type udtUserInfo
    Login    As String  'Login Account
    Role     As Integer 'Permissies/Security
    Afdeling As String  'Afdelingsnaam
    Username As String  'Gebruikersnaam
    Computer As String  'Computername
    Instance As Integer 'Nummer om instance aan te geven als gebruiker de applicatie meerdere keren heeft geopend..
    ReadOnly As Boolean 'Geeft aan of deze instance readonly is.
End Type

'Bij het starten van het programma wordt deze gevuld.
Global guUserInfo As udtUserInfo 'Global userdefined variable.
Global guarrUserinfo() as udtUserinfo 'Global userdefined array

Public sub ShowUserInfo()
    debug.print guUserInfo.Afdeling
'etc
'of 
    with guuserinfo
        debug.print .Afdeling
    end with

end sub

Error code 424 was dacht ik object not found?
writevalue is een variabele van het type variant. Nu is het type niet interessant omdat je geen enkele variabele kan Enabelen of Disabelen. Waarom zou je dat willen? Wat wil je bereiken?

Je kan een integer op 0 zetten, een string op "" een boolean op False en een Variant op Null. Maar je kan geen van allen disabelen. Dat kan allen bij controls en een paar andere objecten.

HTH:D
 
Laatst bewerkt:
Hallo,

Hartstikke bedankt voor je antwoord.

Hmmm heb ook een aantal dagen erover gedaan om de code goed te krijgen voor de treeview. Maar zou eigenlijk willen kijken of ik hem beter kan programmeren. Neemt niet weg dat het zo wel werkt :).

Hmmm writevalue is eigenlijk een textbox. writevalues() is mijn variant. Had ik er bij moeten zetten eigenlijk. Maar het vreemde is heb dat gedeelte ergens anders in mijn programma gezet en krijg er nu geen foutmelding op.

Als je deze melding krijgt bij bijv: een textbox waar zou dit dan aan kunnen liggen? werd niet echt wijzer van de help van excel.

groeten DaDio25
 
Hallo,

Hartstikke bedankt voor je antwoord.

Hmmm heb ook een aantal dagen erover gedaan om de code goed te krijgen voor de treeview. Maar zou eigenlijk willen kijken of ik hem beter kan programmeren. Neemt niet weg dat het zo wel werkt :).

Hmmm writevalue is eigenlijk een textbox. writevalues() is mijn variant. Had ik er bij moeten zetten eigenlijk. Maar het vreemde is heb dat gedeelte ergens anders in mijn programma gezet en krijg er nu geen foutmelding op.

Als je deze melding krijgt bij bijv: een textbox waar zou dit dan aan kunnen liggen? werd niet echt wijzer van de help van excel.

groeten DaDio25
Als je de hongaarse variabelen notatie toepast, dan weet je dat je met een control bezig bent: txtWriteValue is een textbox met die naam. arrWriteValues is een array. marrWriteValues is een array waarvan de scope over heel de module ligt. garrWriteValues is een global array waarvan de scope binnen de gehele applicatie ligt. De laatste moet dan wel worden gedeclareerd binnen een module en niet achter een form.

HTH:D
 
Status
Niet open voor verdere reacties.
Terug
Bovenaan Onderaan