Avatar billede folj Forsker
08. december 2016 - 13:53 Der er 7 kommentarer og
1 løsning

Jeg savner noget i Excel-VBA

Jeg savner en nem måde at starte et array på.
Når jeg tænker tilbage på tiden hvor php-programmering var mit speciale, så var det jo rigtig nemt. Jeg ved godt at php er et meget flexibelt programmeringssprog, men findes der en måde i VBA der ligner, eller blot tillader at man skriver den første post til at array, og hvis der kommer flere poster, så tilføjes de bare?

Herunder har jeg skrevet en løkke hvor jeg gør det ligesom jeg gjorde i php.
kan noget tilsvarende gøres i VBA?
 
For i = 1 to 100 ' looper igennem mine data
  if UserName dit og dat Then
    $MatchUserNameArray[] = UserName  ' laver enkeltdimentionelt array med alle de match der fandtes
  End If
Next i


Jeg bruger i øjeblikket en egen function til at tilføje en post, men den krævet at arrayet allerede findes uanset om der findes nogle poster til at fylde deri:
Function MyAddToArray(MyArray() As Variant, Addition As String)

  Dim ArrayCount As Integer

  ArrayCount = UBound(MyArray, 1)

  ReDim Preserve MyArray(ArrayCount + 1) ' tilføjer en ekstra plads i MyArray
  MyArray(ArrayCount + 1) = Addition ' smider værdi ind i den nu oprettede plads

MyAddToArray = MyArray

End Function


Er der nogen der kender til en måde i VBA hvor man bare kan smide sine match over i et array uanset om arry findes i forvejen eller ej?
Avatar billede kabbak Professor
08. december 2016 - 14:25 #1
hvad med

Function MyAddToArray(UserNameData As Variant) As Variant
    Dim Uddata As String, I As Long

    For I = 1 To UBound(UserNameData, 1)  ' looper igennem mine data
        If UserNameData(I) = "dit" Or UserNameData(I) = "dat" Then
            Uddata = Uddata & UserNameData(I) & ","
        End If
    Next
   
    MyAddToArray = Split(Uddata, ",")
End Function
Avatar billede supertekst Ekspert
08. december 2016 - 14:26 #2
Hvad med string-variabel og split-funktion m.v.?
Avatar billede bvirk Guru
12. december 2016 - 18:06 #3
Den er god nok, folj, med din MyAddToArray - vil bare lige vise ændringer der opfylder flere krav

'()' i føste parameter skal smides væk - en variant kan indefolde et arrray og på den måde kan man gå fra empty til et array med første element - og:

variant er default, så 'as variant' som type angivelse er overflødig - og en variant kan også endeholde en strengværdi - dermed

Function MyAddToArray(MyArray, Addition)
...

Så er der det med at kalde med en variabel der intet indeholder endnu - sådan en variant er empty

Function MyAddToArray(MyArray, Addition)
  If IsEmpty(MyArray) Then MyArray = Array()
 
  'rest of lines
end function


Vi kan teste med:


Sub testit()
    Dim arr 'VIGTIGT ikke '()' bag
    arr = MyAddToArray(arr, "Kurt ")
    arr = MyAddToArray(arr, "korte ")
    arr = MyAddToArray(arr, "starkt")
    Debug.Print Join(arr, "")
End Sub

Men! du arbejder i dine vba liner med MyArray - der er ingen grund til at returnere den og efterfølgende tildele - den har allerede værdien! - dermed er function overkilled

Sub MyAddToArray(MyArray, Addition)

  Dim ArrayCount As Integer
  If IsEmpty(MyArray) Then MyArray = Array()
 
  ArrayCount = UBound(MyArray, 1)

  ReDim Preserve MyArray(ArrayCount + 1) ' tilføjer en ekstra plads i MyArray
  MyArray(ArrayCount + 1) = Addition ' smider værdi ind i den nu oprettede plads
End Sub

Som så skal anvendes således:

Sub testit()
    Dim arr
    MyAddToArray arr, #12/31/2015#
    MyAddToArray arr, " Kurt "
    MyAddToArray arr, "korte "
    MyAddToArray arr, 150
    Debug.Print Join(arr, "")
End Sub


Eller blot, sorry

Sub MyAddToArray(MyArray, Addition)
  If IsEmpty(MyArray) Then MyArray = Array() ' herefter er ubound(MyArray)=-1
  ReDim Preserve MyArray(UBound(MyArray) + 1)
  MyArray(UBound(MyArray)) = Addition
End Sub

Vi kan putte alle simple typer i array'et, men hvad med objekter?

Denne test giver fejl

Sub test2()
    Dim arr, dic As New Dictionary
    dic.Add "fornavn", "Kurt"
    MyAddToArray arr, dic
End Sub

Med mindre vi ændrer sidste linie - og dermed endligt får:

Sub MyAddToArray(MyArray, Addition)
  If IsEmpty(MyArray) Then MyArray = Array()
  ReDim Preserve MyArray(UBound(MyArray) + 1)
  If IsObject(Addition) Then Set MyArray(UBound(MyArray)) = Addition Else MyArray(UBound(MyArray)) = Addition
End Sub

Sub test3()
    Dim i, arr, dic As New Dictionary
    dic.Add "fornavn", "Kurt"
    dic.Add "efternavn", "Hansen"
   
    For Each i In Array(Null, 1, 1, 1.1, 1.1, #12/31/2015#, "Kurt", False, dic)
        MyAddToArray arr, i: Next

'https://msdn.microsoft.com/en-us/library/office/gg278470.aspx

    For Each i In arr
        Debug.Print TypeName(i), VarType(i): Next
    Debug.Print arr(UBound(arr)).Item("fornavn") & " " & _
                arr(UBound(arr)).Item("efternavn")
End Sub
Avatar billede folj Forsker
19. januar 2017 - 11:47 #4
Nu nåede jeg endligt til at få afprøvet Jeres forslag...

@supertekst:
Jeg forstår odt dit forsøg på at lave en kommasepareret tekststreng , og så udnytte funvctionen split(9) til at få det smidt ind i et array.Jeg kan bare i9kke få det til at spille.

Når jeg forsøger atfølge din tankegang, og analyserer koden, så ka jeg heller ikke se hvordan den skal håndtere hvis det er et allerede eksisterende array den skal tilføje en post til.


Jeg ved godt at du er helt oppe på status af guru, og det har du også vist overfor mig ved flere lejligheder.
Så jeg behøves vel ikke at spørge om du selv har testet funktionen?


bvirk:
Jeg kan ikke få dit forslag til at spille...
Function MyAddToArray(MyArray, Addition)
  If IsEmpty(MyArray) Then MyArray = Array()
 
  'rest of lines
End Function

'Vi kan teste med:

Sub testit()
    Dim arr 'VIGTIGT ikke '()' bag
    arr = MyAddToArray(arr, "Kurt ")
    arr = MyAddToArray(arr, "korte ")
    arr = MyAddToArray(arr, "starkt")
'    Debug.Print Join(arr, "")

'    Linjen overfor (Debug.Print) fejler på forkert datatype - derfor har jeg deaktiveret linjen og kører nedenstående test af om det overhovedet er blevet lavet et array - det er der åbenbart ikke
If IsArray(arr) Then
  MsgBox "er et array"
Else
  MsgBox "er ikke et array"
End If

End Sub
Avatar billede supertekst Ekspert
19. januar 2017 - 15:13 #5
Rem Demo
Dim element As String, tabel As Variant
Private Sub Worksheet_Activate()
    element = ""
    tabel = ""

    tilføjElement "AAA"
    tilføjElement "BBB"
    tilføjElement "CCC"
    tilføjElement "DDD"
   
    tabel = Split(element, "|")

Rem Vis fra tabel (eksempel)
    MsgBox tabel(0) & tabel(UBound(tabel) - 1)
End Sub
Private Sub tilføjElement(tekst)
    element = element & tekst & "|"
End Sub
Avatar billede bvirk Guru
21. januar 2017 - 16:56 #6
Hej igen
Jeg forstår ikke hvorfor det ikke virker hos dig  - at du ikke får et array retur !

Før 1. kald af MyAddToArray ligger eksekveringsmæssigt intet - med andre ord udtrykket: isempty(arr) har vædien true

synes lidt der er hugget i runer at arr, nu under navnet MyArray, herefter bliver til et array med:
If IsEmpty(MyArray) Then MyArray = Array()

Hvis du kan følge min ide, så prøv at  singlesteppe og chekke hvad der ikke lykkedes.

Du er vil ops på ikke at efterstille '()' hverken i dim eller parametertype erklæring. Du mikser vel ikke min kode med din egen, uden at være ops på forskelle?

Hvis du sætter et breakpoint på linien:
If IsEmpty(MyArray) Then MyArray = Array()

sætter markøren på linin med sub testit - trykker F5 - maker variabel navnet MyArray, som nu lyser gult, og trækker det til et værdikontroludtryk vindue (som du har puttet tilstede først hvis ikke det var der) -  så skal det fremgå at dens værdi er empty

Ved efterfølgende tastetryk F5 er værdien af MyArray: variant(0 to x) 

Det skal virke og er smart!
Avatar billede folj Forsker
23. januar 2017 - 10:26 #7
@supertekst:
Når jeg afvikler din procedure Worksheet_Activate(), så udskriver den i en msgbox "AAADDD".

Var det det du ville opnå?
Avatar billede supertekst Ekspert
23. januar 2017 - 11:30 #8
Det var jo kun en demo med illustration af noget, der måske kunne hjælpe.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester