W dziale Calc na forum pojawiła się prośba o rozwiązanie problemu wyodrębnienia z zadanego ciągu tekstowego wszystkich fragmentów tekstowych zawartych między zdefiniowanymi znakami i połączenie ich w jeden ciąg rozdzielony wybranym separatorem. W tym konkretnym przypadku chodziło o wyodrębnienie wszystkich liczb zawartych między znacznikami "<id>" oraz "</id>".
Oto przykład takiego ciągu:
Odpowiadając pytającemu, napisałem funkcję użytkownika, którą można zastosować we własnym arkuszu. Funkcję tę nazwałem LICZBY, gdyż chodziło o wyodrębnienie liczb. Po zastanowieniu pomyślałem, że taka funkcja może przydać się jeszcze komuś, więc nieco ją zmodyfikowałem, zmieniłem nazwę na EKSTRAKT i załączam zainteresowanym do ewentualnego wykorzystania.<id>550124</id><guid>238974shdbf23874dgf23hr</guid><id>550125</id><guid>238974shdbf23874dgf23hr</guid><id>550126</id><guid>238974shdbf23874dgf23hr</guid><id>5503454</id> <guid>238974shdbf23874dgf23hr</guid><id>550456</id> <guid>238974shdbf23874dgf23hr</guid><id>550456</id><guid>238974shdbf23874dgf23hr</guid>
EKSTRAKT
Zwraca ciąg złożony z wyodrębnionych fragmentów tekstowych, znajdujących się między zdefiniowanymi znakami wyróżniającymi, wewnątrz innego dłuższego tekstu. Fragmenty te są rozdzielone separatorami wskazanymi przez uzytkownika.
Składnia
Kod: Zaznacz cały
EKSTRAKT(tekst;przed;za;separator)
Przed jest ciągiem poprzedzającym szukany fragment albo adresem komórki zawierającym taki ciąg.
Za jest ciągiem kończącym szukany fragment albo adresem komórki zawierającym taki ciąg.
Separator jest ciągiem rozdzielającym znalezione fragmenty albo adresem komórki zawierającym taki ciąg. Parametr może być pominięty i wtedy separatorem będzie znak spacji.
Uwaga dotycząca pominiętych parametrów.
Z punktu widzenia funkcji parametrem pominiętym jest ten, przed którym nie wystąpił poprzedzający go średnik. W tej sytuacji jako pominięty traktowany może być tylko ostatni ze wszystkich parametrów bo tylko wtedy, pomijając go, możemy pominąć poprzedzający go średnik. Inne choć zasygnalizowane tylko średnikiem, nie są parametrami pominiętymi i są przekazywane do funkcji jako wartość zerowa. Zatem gdy zostanie postawiony średnik poprzedzający ostatni parametr, a sam parametr nie zostanie podany, i tak przekazana zostanie wartość zerowa. Dlatego jeśli parametr Separator miałby nie zostać podany, ale zostanie postawiony średnik go sygnalizujący, należy podać jakąś jego postać, choćby pusty ciąg złożony z dwóch kolejnych znaków cudzysłowu.
Funkcja wymaga, aby ciągi Przed i Za się różniły. Jeśli tak nie będzie, zostanie zwrócona wartość: "Ciągi PRZED i ZA nie mogą być takie same". Jeżeli ciąg Przed nie wystąpi w tekście, zwrócona zostanie wartość: "Brak ciągu PRZED". Jeżeli po zapisie Przed w tekście nie wystąpi zapis Za, zwróconym fragmentem tekstowym będzie fragment od ciągu Przed do końca tekstu.
Przykład:
Kod: Zaznacz cały
=EKSTRAKT(A2;"<id>";"</id>")
Fragmenty rozdzielone są spacją, ze względu na brak czwartego parametru.
Kod: Zaznacz cały
=EKSTRAKT(A2;B2;B3;B4)
Funkcję należy przekopiować do biblioteki "Standard" w kontenerze makr dokumentu Calc, wówczas będzie dostępna tylko w tym dokumencie, albo umieścić ją w bibliotece "Standard" kontenera "Moje makra", wówczas będzie dostępna we wszystkich arkuszach.
Funkcja EKSTRAKT.
Kod: Zaznacz cały
Function ekstrakt(tekst,przed,za, optional separator) as string
REM Funkcja z ciągu tekstowego "tekst" wyodrebnia wszystkie teksty
REM znajdujące sie między ciagami "przed" i "za" i łączy je w jeden
REM nowy ciąg rozdzielając je ciągiem podanym jako "separator".
REM Autor: Jermor, polskie forum Apache OpenOffice i LibreOffice. (2019)
dim t as string
dim pos1 as long, pos2 as long
rem pos1 wyznacza położenie ciągu "przed", pos2 położenie ciągu "za"
dim i as integer,j as integer
if IsMissing(separator) then separator=" "
pos1=1 : pos2=1
t=""
pos1=InStr(pos1,tekst,przed)
if pos1=0 then
ekstrakt="Brak ciągu PRZED"
exit Function ' ciąg "przed" w ogóle nie wystepuje w tekście
End If
If przed=za then
ekstrakt="Ciągi PRZED i ZA nie mogą być takie same"
exit Function
End If
i=len(przed) 'zawiera długośc ciagu "przed"
j=len(za)
do
pos2=InStr(pos1,tekst,za)
t=t & mid(tekst,pos1+i,pos2-pos1-i) & separator
if pos2=0 then exit do
pos1=InStr(pos2+j,tekst,przed)
loop while pos1<>0
ekstrakt=left(t,len(t)-len(separator))
End Function
Nowa składnia wygląda tak:
Składnia
Kod: Zaznacz cały
EKSTRAKT(tekst;przed;za;separator;pierwszy;ile)
Parametr ile jest liczbą całkowitą i informuje ile ciągów ma zostać zwróconych. Jeśli zostanie pominięty przyjmuje się, że wszystkie do końca tekstu.
Nowa wersja kodu poniżej.
Kod: Zaznacz cały
Function ekstrakt(tekst,przed,za, optional separator, optional pierwszy, optional ile) as string
On Local Error goto niemanic
REM Funkcja z ciągu tekstowego "tekst" wyodrebnia wszystkie teksty
REM znajdujące sie między ciagami "przed" i "za" i łączy je w jeden
REM nowy ciąg rozdzielając je ciągiem podanym jako "separator".
REM Autor: Jermor, polskie forum Apache OpenOffice i LibreOffice. (2019)
dim t as string
dim pos1 as long, pos2 as long
rem pos1 wyznacza położenie ciągu "przed", pos2 położenie ciągu "za"
dim i as integer,j as integer, k as integer
if IsMissing(separator) then separator=" "
if isMissing(pierwszy) or not isNumeric(pierwszy) or pierwszy=0 then pierwszy=1
if isMissing(ile) or not isNumeric(ile) then ile=0
pierwszy=int(abs(pierwszy)) : ile= int(abs(ile))
pos1=1 : pos2=1
t="" : k=1
pos1=InStr(pos1,tekst,przed)
if pos1=0 then
ekstrakt="Brak ciągu PRZED"
exit Function ' ciąg "przed" w ogóle nie wystepuje w tekście
End If
If przed=za then
ekstrakt="Ciągi PRZED i ZA nie mogą być takie same"
exit Function
End If
i=len(przed) 'zawiera długośc ciagu "przed"
j=len(za)
do
pos2=InStr(pos1,tekst,za)
If k>=pierwszy and k<=iif(ile=0,k+1,pierwszy+ile-1) then t=t & mid(tekst,pos1+i,pos2-pos1-i) & separator
k=k+1
if pos2=0 then exit do
pos1=InStr(pos2+j,tekst,przed)
loop while pos1<>0
ekstrakt=left(t,len(t)-len(separator))
Exit Function
niemanic:
On Local Error goto 0
ekstrakt=""
End Function