Elektroda.pl
Elektroda.pl
X
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

EXCEL/VBA wyszukiwanie fragmentu tekstu na bazie listy

naszamaja15 05 Feb 2022 13:16 744 8
  • #1
    naszamaja15
    Level 3  
    Witam.
    Mam dwie bazy danych - TABELA OBCA I MOJA TABELA.
    Dla przykładu są one w załączonym pliku w jednym arkuszu, ale docelowo będą w oddzielnych arkuszach (20 - 30 tysięcy wierszy).

    Chcę stworzyć własny indeks, który będzie zawierał informacje z MOJA TABELA po znalezieniu ich w TABELA OBCA.
    Chcę aby znalazł dane z MOJA TABELA (kol C-D) w TABELA OBCA (kol A) i podał je w INDEKS WŁASNY (kol F).

    W MOJA TABELA dane są zawsze dokładnie takie same, zawierają Markę i Rodzaj.
    W TABELA OBCA dane znajdują się w jednej kolumnie. Marka jest zawsze tak samo opisana i bez problemu wyszukuję ją funkcjami.
    Pobieram z nazwy 3 pierwsze znaki przykładowo "AEOLUS" pobieram do Indeksu "AEO".

    Potrzebuję wyszukać w komórkach A, który Rodzaj (kol D) dla Marka (kol C) z MOJA TABELA jest w nich zapisany.
    Przykładowo w komórce A3 jest Marka "AEOLUS" Rodzaj "AH05".
    Ten sam Rodzaj mogą mieć różne Marki.

    Gdyby Rodzaj był zawsze tak samo opisany jak w kolumnie D. Problem bym rozwiązał funkcjami i funkcją UDF
    Code: vbscript
    Log in, to see the code


    (pomógł przy innym problemie Maciej Gonet)

    Rodzaj opisywany jest jednak różnie. Przykładowo w komórce A3 rodzaj "AH05" opisany jest jako "AH 05-". Może to być różnie opisane przykładowo " AH05 "; " AH-05 "; " AH 05"; "AH05-".
    Próbowałem użyć różnych funkcji, przykładowo gdyby w funkcji ZNAJDŹ można było użyć symbolu wieloznacznego "*". Niestety nie radzę sobie
  • Helpful post
    #2
    Maciej Gonet
    VBA, Excel specialist
    naszamaja15 wrote:
    gdyby w funkcji ZNAJDŹ można było użyć symbolu wieloznacznego "*"
    W funkcji ZNAJDŹ nie można, ale jest bardzo podobna funkcja SZUKAJ.TEKST, w której można używać symboli wieloznacznych. Różni się od ZNAJDŹ (poza symbolami wieloznacznymi) tym, że nie rozróżnia małych/wielkich liter.

    Jeśli z tą funkcją sobie poradzisz to będziesz miał satysfakcję.

    Ja jednak mam poważne obawy. Twoje dane są bardzo nieregularne, a wzorce krótkie. W związku z tym użycie gwiazdki, która jak wiadomo zastępuje dowolną liczbę znaków jest dość ryzykowne, bo dopasowanie może być w dość odległych fragmentach tekstu, a więc przypadkowe. Tu należałoby ograniczyć liczbę znaków dopisanych wewnątrz kodu od 0-1, maksimum 2.
    Poza tym nie jest stałe miejsce, gdzie mogą się pojawić te dodatkowe znaki, bo kody mają po 2-3 litery. Może ktoś biegły w wyrażeniach regularnych umiałby to opanować.

    To co mnie się udało dopasować, to utworzenie 2 kolumn wzorcowych - jedna bez znaków dodatkowych, druga ze znakiem zapytania pomiędzy literami a cyframi (kol. E). Funkcją SZUKAJ.TEKST próbuję to dopasować (kol. G), a potem wygenerować kod (kol. H). Te 2 kolumny można oczywiście połączyć, ale ja nie lubię megaformuł.

    Ale to rozwiązanie nie jest doskonałe. Przykłady problemów:
    W komórce A6 występują 2 kody: ACE 2 i AH03. Dlaczego został wybrany ten drugi? Bo jest pierwszy w kolejności na liście w kol. D. Ale tak naprawdę nie wiem, dlaczego właśnie on jest w rozwiązaniu wzorcowym.
    W komórce A13 sekwencja liter "ACE 2" występuje przed kodem "ACE3", więc ona została pierwotnie wskazana. Ewentualnym remedium mógłby być wymóg, że kod musi być poprzedzony spacją. Jeśli dopisze się to w formułach, to w A13 wynik jest poprawny - ale czy zawsze przed kodem jest spacja, a nie np. przecinek?

    Do wyodrębnienia pierwszego słowa zastosowałem prostą funkcję UDF:
    Code: vbscript
    Log in, to see the code

    Można ją jednak zastąpić zwykłymi funkcjami, np.:
    Code: text
    Log in, to see the code
    To jest wpisane w G3, w innych komórkach jest UDF - do wyboru.
    Przetestuj sobie na większej próbce danych, ale grunt jest dość grząski.
  • #3
    naszamaja15
    Level 3  
    W komórce A6 są przypadkowo dwa kody. Dane były tworzone ręcznie, żeby nie podawać konkretnych.

    Natomiast muszę zwrócić uwagę na problem z komórki A13, taka sekwencja liter może wystąpić w opisie.
    Zastanawiałem się właśnie nad spacjami poprzedzającymi kod. Normalnie przed kodem powinna być spacja, jedynie przy "palcówkach" kod jest poprzedzony znakiem, ale to już w niewielkiej ilości rekordów.

    Dam znać jak pójdzie, w szczególności z dużo ilością danych.

    Wielkie dzięki.
  • #4
    naszamaja15
    Level 3  
    Przy znikomej ilości danych w miarę chodzi. Ale przy większej ilości danych już jest problem.

    Przykładowo w A3 jest "AH 05-" w A4 "AH 03" i podaje właściwe dane.
    Natomiast przy większej ilości danych, kiedy w dowolnej komórce kolumny "A" jest "AH 5" nie znajduje. Dopiero kiedy do kolumny E dodam "AH? 5".
    Nie ma w tym logiki bo przecież "?" powinien zastąpić dowolny znak.

    Poza tym, kiedy jest "AH 5", a w innej komórce jest "AH", "AH" nie znajduje.
    Tu to oczywiście mój "pośpiech". Nie podałem pełnej listy danych przykładowych i można było wnioskować, że każdy Rodzaj ma opis literowy + liczby. O tym, że mogą wystąpić same litery lub cyfra + litera nie napisałem.

    Przeglądam całą bazę i kombinuję.
    Twoje formuły bardzo dużo mi w tym pomagają.

    Widzę jednak, że muszę podszkolić się z Accessa, bo Excel z tak dużą bazą danych już nie jest tym samym programem.

    Dzięki serdeczne za pomoc
  • #5
    Maciej Gonet
    VBA, Excel specialist
    Bardzo istotne jest, aby uwzględnić wszystkie możliwe schematy danych. Tu były uwzględnione schematy: 2 znaki zdefiniowane + (0÷1) znak dowolny + 2 znaki zdefiniowane albo 3 znaki zdefiniowane + (0÷1) znak dowolny + 1 znak zdefiniowany. Fragment "AH 5" do tego nie pasuje, jeśli wzorzec zdefiniowany jest "AH05" lub "AH?05", bo brakuje zera. Trzeba byłoby dodać jeszcze wzorce "AH5" i "AH?5".
    Obawiałem się, że to nie będzie takie proste. Większą elastyczność zapewniłby kod VBA wykorzystujący wyrażenia regularne, ale ja nie jestem w tym biegły.
    Ale nawet tą uproszczoną metodą wyniki byłyby lepsze gdyby wszystkie wzorce były uwzględnione.
  • #6
    Prot
    Level 38  
    Maciej Gonet wrote:
    Większą elastyczność zapewniłby kod VBA wykorzystujący wyrażenia regularne

    Z wykorzystaniem wyrażeń regularnych można tą procedurę przeprowadzić np. tak jak na zrzucie i w załączonym pliku :D
    EXCEL/VBA wyszukiwanie fragmentu tekstu na bazie listywypind.PNG Download (42.12 kB)
    Skrót ctrl+i wywołuje makro, które wyszukuje indeksy ze stringów w kolumnie A.
    Jeśli wystąpią dwa indeksy to są listowane w kolumnie obok :spoko:

    INDEKSP...zip Download (16.25 kB)Points: 2.5 for user
  • #7
    clubs
    Level 38  
    Czy to ma być "wyciągane" na podstawie listy czyli marki i rodzaju? czy tylko chodzi o wyciągnięcie z tekstu samego np. "AH05"
    Tak jak kolega @Maciej Gonet napisał za mało danych przykładów (a czy może być np. "DH05" czy inny? czy wszystko zaczyna się od A?) i nie chodzi tu nawet o wyrażenia regularne bo takie, rzeczy można nawet 'like-em' załatwić.
  • #8
    naszamaja15
    Level 3  
    Ma być "wyciągane" na podstawie listy marki rodzaj.

    Sprawdziłem pełną bazę i w załączonym pliku uzupełniłem przykłady.
    Plik ten różni się od poprzedniego jest "pełniejszy"

    W kolumnie A "wyboldowałęm" dane do wyszukiwania.
    Do Moja Tabela dodałem kolumnę Rodzaj do Indeks, ponieważ w danych Rodzaj może być przykładowo TRANS VAX, a do indeksu ma być nie ten pełny opis tylko TRV.


    Dodałem przykładową listę do uzupełnienia.
    Nie mam wystarczającej wiedzy, ale wydaje mi się, że na bazie takiej listy łatwiej coś "stworzyć".
    Wprawdzie nie mam takiej listy, ale jeśli faktycznie pomoże w rozwiązaniu, to ją stworzę.

    Rodzaj może być różnie opisany, dlatego dodałem kolumny Rodzaju.
    W kolumnach Rodzaj - Rodzaj5 umieściłem opisy Rodzaju, które są w Tabela Obca.
    W ostatniej kolumnie jest Rodzaj do Indeksu.

    Mam nadzieję, opisałem to wystarczająco zrozumiale.
  • #9
    clubs
    Level 38  
    naszamaja15 wrote:
    Dodałem przykładową listę do uzupełnienia.

    Teraz daje to "obraz", że nie ma możliwości aby poprawnie "wyciągnąć" te dane przy np.
    Code: dos
    Log in, to see the code

    Nawet przy użyciu "wyrażeń regularnych" nakładaniu "maski" czy cięciu "spacji" itp. nic nie da bo jest kolejna cyfra. (małym "światełkiem" jest to, żeby lista była ułożona alfabetycznie, to można wyciągnąć drugie "wystąpienie")