• Privacywetgeving
    Het is bij Helpmij.nl niet toegestaan om persoonsgegevens in een voorbeeld te plaatsen. Alle voorbeelden die persoonsgegevens bevatten zullen zonder opgaaf van reden verwijderd worden. In de vraag zal specifiek vermeld moeten worden dat het om fictieve namen gaat.

Ontfilteren Array

Status
Niet open voor verdere reacties.

Peter B

Gebruiker
Lid geworden
8 feb 2007
Berichten
672
Tsja. Ik wist even niet echt een betere titel te verzinnen.

Ik ben mij (verder) aan het verdiepen in arrays. Met dank aan (o.a.) de site van snb begin ik het idee te krijgen er steeds meer van te begrijpen. Maar nu kom ik kennelijk bij een stukje wat voor mij "hogere wiskunde" is, ofwel ... Ik begrijp het niet. En dus de vraag of iemand mij kan helpen.

De situatie
Ik lees een groot bestand in (platte tekst). In dit bestand zitten producten met steeds herhalende regels. Deze zijn herkenbaar aan de regelnaam. Ik lees het bestand in Excel in een array. Vervolgens laat ik er een aantal bewerkingen op los. In eerste instantie deed ik dit door door de array heen te loopen. Maar dat kan slimmer. In het bestand moet een aantal regels volledig worden vervangen. Dit is relatief eenvoudig met:
Code:
arrInput = Application.Substitute(arrInput, "~Te vervangen regel1~", "~Vervangende tekst1~")
arrInput = Application.Substitute(arrInput, "~Te vervangen regel2~", "~Vervangende tekst2~")
Dat werkt mooi (en snel)

Het probleem
Ik loop echter vast op het volgende. Ik wil per product een regel vervangen door een regel met een teller. Dit kan niet met Substitute (want dat is vervangen met één string). Ik dacht dit te doen door te filteren op de specifieke regel en door deze gefilterde lijst heen te loopen (dat scheelt het scannen van heel veel onnodige regels). Echter ... Het werkt niet helemaal als de werkbladfunctie om te filteren, waarbij je het filter weer uit kunt zetten (en dus het hele bestand weer ziet).

De vraag
Zie ik iets over het hoofd? Bestaat er wel een ontfilterfunctie? Zo ja, hoe doe ik dit? Zo nee, hoe kan ik dit anders (handig & snel) oplossen?

Ik denk niet dat een voorbeeldbestand veel zin heeft, maar indien gewenst wil ik deze met alle plezier maken. De structuur is ongeveer als volgt (de productkenmerken variëren in aantal tussen de 50 en 150. Omdat de productnaam niet uniek is wil ik deze voorzien van een volgnummer:
Code:
Header
Productnaam
Productkenmerk1 Omschrijving
Productkenmerk2 Omschrijving
Productnaam
Productkenmerk1 Omschrijving
Productkenmerk2 Omschrijving
Productkenmerk3 Omschrijving
Productkenmerk4 Omschrijving
etc.
 
zie eens: (vervangen in een string is eenvoudiger dan in een array)

Code:
Sub M_snb()
    c00 = "aa bb bb bb aa cc cc aa dd dd aa ee ee"
    
    For j = 1 To 5
       c00 = Replace(c00, "aa", j, , 1)
    Next
    
    MsgBox c00
End Sub
 
Slim! Dat wordt sowieso terug naar de tekentafel. Een probleem waar ik dan wel tegenaan loop is dat niet altijd een exacte tekst wil zoeken/ vervangen. Dus wat ik zou willen is zoeken met een wildcard om niet alleen aa maar ook ab te vervangen. Helaas werkt vervangen voor deze regel niet.
Code:
c00 = Replace(c00, "[COLOR="#FF0000"]a*[/COLOR]", j, , 1)
 
Is dit een oefening in Arrays, of ben je een "echt" probleem aan het oplossen, wellicht met de verkeerde tool? Wat is je brondata en waar moet het uiteindelijk naartoe?
 
Ik ben een "echt" probleem aan het oplossen maar dan wel met de middelen die ik heb. Ik meende dit te doen door het in te lezen bestand om te zetten naar een array en dan de entries uit het array te bewerken voordat ik e.e.a. daadwerkelijk in Excel zet.

Dit werkt, maar duurt erg lang. Vandaar dat ik de code ben begonnen te optimaliseren. Dat was de initiële vraag. Nu blijkt er echter een betere (snellere) oplossing mogelijk te zijn nl. het in te lezen bestand als string bewerken, dan omzetten naar array en dan in Excel zetten.

Ik ben inmiddels verder met mijn zoek en vervangvraag m.b.t. strings. Hierbij het voorbeeld:
Code:
Sub testje()
Dim c00         As String
Dim objRegEx    As Object
Dim objMatch    As Variant
Dim intIndex    As Integer

c00 = "aa bb bb bb aa cc cc abc dd dd aa ee ee abc"
Set objRegEx = CreateObject("vbscript.regexp")
objRegEx.Global = True
objRegEx.IgnoreCase = True
objRegEx.Pattern = "a[A-Z]c"

If (objRegEx.test(c00) = True) Then
    Set objMatch = objRegEx.Execute(c00)
    For intIndex = 0 To objMatch.Count - 1
        c00 = Replace(c00, objMatch(intIndex), "blabla" & intIndex + 1, , 1, vbTextCompare)
    Next
    Debug.Print c00
End If
End Sub

Output: aa bb bb bb aa cc cc blabla1 dd dd aa ee ee blabla2

Ik ben er best trots op ondanks dat het natuurlijk het betere "jatwerk" is ... :)
 
Prima :thumb:

Edoch:
Code:
Sub M_snb()
    c00 = "aa bb bb bb aa cc cc aa dd dd aa ee ee abc gg hh abcd ff gg"
    sn = Filter(Filter(Split(c00), "a"), "c")
    
    For j = 0 To UBound(sn)
       c00 = Replace(c00, sn(j), "voorbeeld_" & j + 1, , 1)
    Next
    
    MsgBox c00
End Sub
 
Probleem is wel dat je geen echte gegevens toont.
Maar goed, dat houdt je zelf aan de gang.
 
Klopt. Ik wil graag begrijpen hoe ik iets op kan lossen. Met een pasklaar antwoord gaat dat meestal minder goed. Door aanpassen/ tweaken van de aangeboden oplossing ga je ook begrijpen hoe iets werkt.

Ik ben er achter gekomen dat de filter-optie niet werkt bij het ontbreken van spaties. Ook komen er vreemde tekens voor in de te vervangen string. En is het aantal karakters niet te voorspellen. V.w.b. de echte data. Het gaat om een XML-bestand, met de te vervangen waarden dus tussen tags. De tags waarop gezocht wordt hebben geen opties, dus geen patroon als <a bla=2>

Ik heb het search pattern hierop aangepast in "mijn" code naar: "<a>(.+?)</a>".
Dit zorgt er voor dat bv. <a>bla</a>, <a>+-()</a> en <a>*</a> etc. worden gevonden (en dus kunnen worden vervangen). Natuurlijk sta ik open voor andere oplossingen :)
 
Mja, maar wellicht is je probleem eenvoudig op te lossen met iets anders dan VBA, zoals PowerQuery (get & transform). Maar zonder start- en eind-punt kunnen we niet adviseren.
 
Status
Niet open voor verdere reacties.
Terug
Bovenaan Onderaan