Wyodrebnianie ilosci tych samych liczb z konca ciagu.

Użytkowanie arkusza kalkulacyjnego
xg4m3r
Posty: 4
Rejestracja: pn kwie 08, 2019 11:55 pm

Wyodrebnianie ilosci tych samych liczb z konca ciagu.

Post autor: xg4m3r »

Witam
Mam problem z dwoma kwestiami, mam nadzieje ze bedziecie w stanie mi pomoc :)

Otoz, mamy pewien ciag liczb, kolumna A jest poczatkiem ciagu a kolumna J jest jego koncem. Ostatnie piec cyfr sa tymi samymi wartosciami (patrz pierwszy rzad).
I teraz problem polega na tym ze chcialbym aby w komorce L byla podana wartosc "5" ktora odpowiada za ilosc tych samym wartosci liczac od konca ciagu.
Jesli dodam kolejna jedynke do nastepnej kolumny wtedy wartosc = 6, jesli 0 to wartosc = 1 (jako ze jest tylko jedna ta sama liczba od konca ciagu).
Jesli bylaby taka mozliwosc to kiedy komorka L osiagnie pewna wartosc to zeby zmienil sie kolor tla tej komorki, np. 2 to zolty a 5 to czerwony.
Na zdjeciu zrobilem kilka przykladow aby latwiej bylo to zrozumiec.
Obrazek

Bardzo dziekuje za pomoc :)
Pozdrawiam
OpenOffice 4.1.2 / Windows 7
Jan_J
Posty: 4558
Rejestracja: pt maja 22, 2009 1:20 pm
Lokalizacja: Wrocław

Re: Wyodrebnianie ilosci tych samych liczb z konca ciagu.

Post autor: Jan_J »

Chętnie bym zobaczył sprytne rozwiązanie wykorzystujące składnię wektorową formuł.
Sam zrobiłem rzecz narzucającą się, tj. realizację algorytmu zliczania wstecz za pomocą funkcji w Basicu.

Kod: Zaznacz cały

rem
rem zlicza liczbę jednakowych wyrazów na końcu ciągu a
rem opracował zespół forum.openoffice.org/pl, kwiecień 2019
rem licencja public domain
rem
function count_tail(a as array) as integer
  n = ubound(a, 2)
  do while isempty(a(1,n))
    n = n-1
    if n = 0 then 
      count_tail = 0
      exit function
    end if
  loop
  v = a(1,n)
  k = n
  do while (a(1,k) = v)
    k = k-1
    if k = 0 then exit do
  loop
  count_tail = n-k
end function
Pierwsza pętla cofa się do ostatniej wypełnionej komórki; druga cofa się tak długo, jak długo natrafia na tę samą wartość.
Zastosowałem śmieszne IF / EXIT w pętlach, bo wydaje się, że warunki AND są obliczane o zgrozo, bez skrótów;
np. WHILE (n>0) AND (a(n)=v) generuje błąd przekroczenia zakresu zamiast `po ludzku` skończyć na n>0 == F w przypadku n równego 0.

Przygotowanie do użycia: Narzędzia/Makra/Basic/Zarządzaj
w bieżącym skoroszycie załóż nowy moduł i wklej do niego powyższy kod.

Użycie w formule: = count_tail(zakres_wiersz), np. =count_tail(A1:G1)
JJ
LO (7.6|24.2) ∙ Python (3.12|3.10) ∙ Unicode 15 ∙ LᴬTEX 2ε ∙ XML ∙ Unix tools ∙ Linux (Rocky|CentOS)
Awatar użytkownika
Jermor
Posty: 2238
Rejestracja: sob paź 12, 2013 11:09 am
Kontakt:

Re: Wyodrebnianie ilosci tych samych liczb z konca ciagu.

Post autor: Jermor »

Szanowny Janie wydaje mi się, że do funkcji COUNT_TAIL zawartość komórek pustych jest przekazywana jako 0 i w związku z tym nie wylicza ona prawidłowo tego co powinna.
W każdym razie po jej włączeniu do arkusza nie działa dobrze. Przynajmniej u mnie.
Sam algorytm jest uniwersalny, nie zależy od tego jakie liczby są wpisane do komórek ani ile ich jest.
Spróbowałem rozwiązać ten problem tylko za pomocą wbudowanych funkcji i standardowych formuł.
Jednak z następującymi ograniczeniami.
Wartościami komórek jest jedynie 0, 1 albo komórka jest pusta a komórki puste jeśli występują to tylko w końcowych kolumnach.
Ilość wykorzystanych komórek w wierszu wynosi 11 (od kolumny A do K) i nie może być większa niż 30 (to wynika z użytej funkcji ZŁĄCZ.TEKSTY).
Oto moje rozwiązanie:
Za pomocą funkcji ZŁĄCZ.TEKSTY utworzyłem ciąg odwrotny czyli konkatenację komórek w kolumnach od K do A
Przy pomocy funkcji ZNAJDŹ znajduję w tym ciągu pierwsze wystąpienie cyfry 1
Przy pomocy funkcji ZNAJDŹ znajduję w tym ciągu pierwsze wystąpienie cyfry 0
Moduł z różnicy między tymi wartościami to liczba ostatnich takich samych cyfr.
Położenie każdej z cyfr musi być jednak skorygowane ze względu na to, że gdy cyfra nie wystąpi, funkcja zgłosi błąd #ARG, dlatego gdy cyfry nie ma w ciągu wstawiana jest długość ciągu pomniejszona o 1
Całość formuł można oczywiście połączyć w jedną złożoną - i bardzo nieczytelną - formułę. Aby czytelnik mógł sobie jednak prześledzić logikę tego rozwiązania załączam arkusz z poszczególnymi elementami tej formuły.
Załączniki
xg4m3r.ods
(10.37 KiB) Pobrany 95 razy
AOO 4.1.15, LO 7.5.9 (x64) na Windows 10 64bit
Ważne!
Jeśli twój problem został rozwiązany, wróć do swojego pierwszego postu, przejdź do edycji i dopisz [SOLVED] w temacie.
Inni, którzy mają podobny problem, będą wiedzieli, że istnieje jego rozwiązanie.
Jan_J
Posty: 4558
Rejestracja: pt maja 22, 2009 1:20 pm
Lokalizacja: Wrocław

Re: Wyodrebnianie ilosci tych samych liczb z konca ciagu.

Post autor: Jan_J »

Testy robiłem na LO Calc 6.1.5.
isempty(x) sprawdza, czy komórka jest pusta; w pętli `odcina się` niewypełniony blok końcowy zakresu.
Jeśli odetniemy cały zakres, to znaczy że jest on pusty i wynikiem jest 0.
W przeciwnym razie pozostaje n komórek, z których przynajmniej ostatnia jest wypełniona.
Bierzemy ją i cofamy się dalej, tak długo jak wartość się nie zmienia, lecz nie dalej niż do początku zakresu. Liczba cofnięć + 1, albo długość bloku - indeks pierwszej niezgodności jest równa liczbie powtórzeń na końcu.

Więc algorytm wygląda OK. Być może zakradł się tzw. błąd semantyczny -- że system działa inaczej niż myślimy. Spróbujmy przeanalizować:

Wątpię czy AOO Calc ma inną specyfikację funkcji isempty. Funkcja użyta w formule dostaje od arkusza tablicę dwuwymiarową wartości variant; być może u Apache zawiera ona zera w miejscu pustych danych? to byłby słaby punkt AOO; sprawdzę przy najbliższej okazji.
JJ
LO (7.6|24.2) ∙ Python (3.12|3.10) ∙ Unicode 15 ∙ LᴬTEX 2ε ∙ XML ∙ Unix tools ∙ Linux (Rocky|CentOS)
xg4m3r
Posty: 4
Rejestracja: pn kwie 08, 2019 11:55 pm

Re: Wyodrebnianie ilosci tych samych liczb z konca ciagu.

Post autor: xg4m3r »

Bardzo Wam dziękuję za pomoc.
Jermor ma rzeczywiście rację, funkcja zlicza pustą komórkę jako 0 i wygląda to tak:
Obrazek
Sprawdziłem w LO ale jest dokładnie tak samo.
OpenOffice 4.1.2 / Windows 7
Awatar użytkownika
Jermor
Posty: 2238
Rejestracja: sob paź 12, 2013 11:09 am
Kontakt:

Re: Wyodrebnianie ilosci tych samych liczb z konca ciagu.

Post autor: Jermor »

Szanowny Janie, rzeczywiście w LO funkcjonuje prawidłowo. Sprawdzałem to tylko w AOO bowiem nasz respondent, w stopce, sygnalizował korzystanie z AOO 4.1.2.
AOO 4.1.15, LO 7.5.9 (x64) na Windows 10 64bit
Ważne!
Jeśli twój problem został rozwiązany, wróć do swojego pierwszego postu, przejdź do edycji i dopisz [SOLVED] w temacie.
Inni, którzy mają podobny problem, będą wiedzieli, że istnieje jego rozwiązanie.
Jan_J
Posty: 4558
Rejestracja: pt maja 22, 2009 1:20 pm
Lokalizacja: Wrocław

Re: Wyodrebnianie ilosci tych samych liczb z konca ciagu.

Post autor: Jan_J »

Jermor pisze:Sprawdzałem to tylko w AOO bowiem nasz respondent, w stopce, sygnalizował korzystanie z AOO 4.1.2.
Słusznie. Na razie jest tak, że mam albo chwilę czasu wolnego, albo dostęp do AOO. W sytuacji kiedy zdarzy się spełnienie obu warunków naraz, zidentyfikuję problem i spróbuję wypracować rozwiązanie.

A tu mamy niezgodność:
xg4m3r pisze:Sprawdziłem w LO ale jest dokładnie tak samo.
Jermor pisze:rzeczywiście w LO funkcjonuje prawidłowo
i też trzeba ją wyjaśnić...
Jan_J pisze:Testy robiłem na LO Calc 6.1.5.
JJ
LO (7.6|24.2) ∙ Python (3.12|3.10) ∙ Unicode 15 ∙ LᴬTEX 2ε ∙ XML ∙ Unix tools ∙ Linux (Rocky|CentOS)
Awatar użytkownika
Jermor
Posty: 2238
Rejestracja: sob paź 12, 2013 11:09 am
Kontakt:

Re: Wyodrebnianie ilosci tych samych liczb z konca ciagu.

Post autor: Jermor »

Nie wiem, czy przy okazji tego postu nie ujawniło się coś więcej.
Plik z dedykowaną funkcją COUNT_TAIL zapisany w LO 6.1.5 po otwarciu w AOO 4.1.6 pokazuje formułę następująco:

Kod: Zaznacz cały

='count_tail'(A2:K2) 
wyświetlając jako wynik #ODWOŁANIE
Działanie funkcji daje się przywrócić po zmianie nazwy polegającej na usunięciu podkreślnika, ale z błędnym wyliczaniem wyniku.
Co ciekawe utworzenie (wkopiowanie) funkcji do pliku AOO z nazwą zawierającą podkreślnik nie sygnalizowało żadnych problemów. Funkcja, choć błędnie, wykonywała działanie.
Zapisanie takiego pliku w AOO i otworzenie w LO powoduje takie same skutki. Kod formuły jest zmieniony, przez ujęcie jej nazwy w pojedyncze apostrofy, zaś wynikiem wyświetlanym w komórce jest #REF (czyli to samo co w AOO - Odwołanie).
W LO wystarczy usunąć apostrofy i zatwierdzić formułę by zaczęła działać prawidłowo.
Gdy nazwa funkcji nie zawiera podkreślnika działa ona w obu systemach Calc. Choć w AOO niepoprawnie.
AOO 4.1.15, LO 7.5.9 (x64) na Windows 10 64bit
Ważne!
Jeśli twój problem został rozwiązany, wróć do swojego pierwszego postu, przejdź do edycji i dopisz [SOLVED] w temacie.
Inni, którzy mają podobny problem, będą wiedzieli, że istnieje jego rozwiązanie.
Jan_J
Posty: 4558
Rejestracja: pt maja 22, 2009 1:20 pm
Lokalizacja: Wrocław

Re: Wyodrebnianie ilosci tych samych liczb z konca ciagu.

Post autor: Jan_J »

Łoj, źle się dzieje. Dominacja implementacji nad specyfikacją jako immanentny paradygmat postnowoczesności?
From https://wiki.openoffice.org/wiki/Docume ... m_Overview
Markers

A OpenOffice.org Basic program can contain dozens, hundreds, or even thousands of markers, which are names for variables, constants, functions, and so on. When you select a name for a marker, the following rules apply:

[*] Markers can only contain Latin letters, numbers, and underscores (_).
[*] The first character of a marker must be a letter or an underscore.
JJ
LO (7.6|24.2) ∙ Python (3.12|3.10) ∙ Unicode 15 ∙ LᴬTEX 2ε ∙ XML ∙ Unix tools ∙ Linux (Rocky|CentOS)
Jan_J
Posty: 4558
Rejestracja: pt maja 22, 2009 1:20 pm
Lokalizacja: Wrocław

Re: Wyodrebnianie ilosci tych samych liczb z konca ciagu.

Post autor: Jan_J »

Z wstępnych oględzin pod debuggerem działania funkcji count_tail widać, że
  • w Libre parametr a jest tablicą obiektów variant/x, przy czym x jest double albo string, albo empty,
  • zaś w Apache występują tylko typy double albo string; z pustej komórki robi się double równe 0.
Dzieje się to na etapie przygotowywania parametrów dla wywołanej funkcji. A to znaczy, że funkcja napisana w Basicu dla Apache Calca nie ma możliwości rozróżnienia między zerem a pustą komórką. Smutne, ale poczytywałbym to za usterkę Apache'a. Uważam, że po przeszukaniu bugzilli Apache można próbować zgłosić błąd.

W związku z problemem,
https://forum.openoffice.org/en/forum/v ... hp?t=53715
https://forum.openoffice.org/en/forum/v ... hp?t=31361
Ten typ tak ma... tylko że przydałaby się wzmianka w dokumentacji. Bo wnioskowanie z testów to marna metoda...

No chyba, żeby oprócz zasięgu zakresu przekazywać dodatkowy parametr z aktualną liczbą komórek. Sztuczne i sprzyjające omyłkom. Ale kod jest public domain, wolno go zmodyfikować w każdym kierunku.

Testowałem Apache Calc 4.1.6 vs Libre Calc 6.1.3. W tym zestawie nie napotkałem na żadne konflikty związane z niezrozumieniem nazwy funkcji, niezależnie od tego który Calc zapisywał dokument.
JJ
LO (7.6|24.2) ∙ Python (3.12|3.10) ∙ Unicode 15 ∙ LᴬTEX 2ε ∙ XML ∙ Unix tools ∙ Linux (Rocky|CentOS)
Awatar użytkownika
Jermor
Posty: 2238
Rejestracja: sob paź 12, 2013 11:09 am
Kontakt:

Re: Wyodrebnianie ilosci tych samych liczb z konca ciagu.

Post autor: Jermor »

Przyjrzałem się raz jeszcze temu o czym napisałem i...
Bezpośrednio nad kolumną zawierającą wyniki funkcji COUNT_TAIL umieściłem tytuł tej kolumny, wpisując Count_tail. Okazuje się, że to jest powodem takiego dziwacznego działania. Dokładniej, włączona opcja "Automatycznie znajdź etykiety kolumn i wierszy" w "Opcje -> OpenOffice Calc -> Oblicz".
Po zmianie tytułu obliczenia się wykonują, także po wyłączeniu tej opcji.
AOO 4.1.15, LO 7.5.9 (x64) na Windows 10 64bit
Ważne!
Jeśli twój problem został rozwiązany, wróć do swojego pierwszego postu, przejdź do edycji i dopisz [SOLVED] w temacie.
Inni, którzy mają podobny problem, będą wiedzieli, że istnieje jego rozwiązanie.
Jan_J
Posty: 4558
Rejestracja: pt maja 22, 2009 1:20 pm
Lokalizacja: Wrocław

Re: Wyodrebnianie ilosci tych samych liczb z konca ciagu.

Post autor: Jan_J »

Workaround, czyli łata. Funkcja count_tail zyskuje nowy argument opcjonalny n, który deklaruje długość analizowanego ciągu.

Kod: Zaznacz cały

    rem
    rem zlicza liczbę jednakowych wyrazów na końcu ciągu a
    rem opracował zespół forum.openoffice.org/pl, kwiecień 2019
    rem licencja public domain
    rem
    function count_tail(a as object, optional n as integer) as integer
      if ismissing(n) then
        n = ubound(a, 2)
      elseif n > ubound(a, 2) then
        n = ubound(a,2)
      endif
      do while isempty(a(1,n))
        n = n-1
        if n = 0 then
          count_tail = 0
          exit function
        end if
      loop
      v = a(1,n)
      k = n
      do while (a(1,k) = v)
        k = k-1
        if k = 0 then exit do
      loop
      count_tail = n-k
    end function
Jeżeli jesteśmy uprzejmi i nie zostawiamy `dziur` w danych, długość bloku wyliczymy w formule funkcją count albo counta.
Czyli zliczenie przy jej użyciu długości ogona w Apache OO Calc będzie wymagać wywołania postaci

Kod: Zaznacz cały

=count_tail(A1:H1; ile.niepustych(A1:H1))
Gdyby pozostawić `dziurę` w danych, wyniki formuły będą dotyczyły zbyt krótkiego obszaru.

W bardziej cywilizowanym libreoffice, który odróżnia 0 od wartości pustej w tablicach, wystarczy wywołanie w dawnej postaci

Kod: Zaznacz cały

=count_tail(A1:H1)
Ale także w tym przypadku użycie parametru n nie zaszkodzi.

Nie testowałem nowego rozwiązania pod Apache, ale sądzę że wszystko powinno być OK.

PS. Dokumentacja dla użytkowników dot. przekazywania argumentów do funkcji istnieje, choć jest niezbyt głęboka:
https://wiki.openoffice.org/wiki/Docume ... to_a_macro
Da się z niej wyczytać, że dane przekazywane są przez wartość, ale nie ma rozważań, czy pustej komórce odpowiada wartość DOUBLE 0.0, czy EMPTY.
JJ
LO (7.6|24.2) ∙ Python (3.12|3.10) ∙ Unicode 15 ∙ LᴬTEX 2ε ∙ XML ∙ Unix tools ∙ Linux (Rocky|CentOS)
Awatar użytkownika
Rafkus
Posty: 513
Rejestracja: czw kwie 12, 2018 10:26 pm

Re: Wyodrebnianie ilosci tych samych liczb z konca ciagu.

Post autor: Rafkus »

Tak z ciekawości przetestowałem ten kod w OO, działa z jednym zastrzeżeniem: pojawia się błąd "Indeks poza zakresem" gdy zadeklarowany ciąg jest w całości pusty (ILE.NIEPUSTYCH(A1:H1)=0)
Pozwoliłem sobie na nieznaczną modyfikację (dodałem warunek i skok)

Kod: Zaznacz cały

rem
    rem zlicza liczbę jednakowych wyrazów na końcu ciągu a
    rem opracował zespół forum.openoffice.org/pl, kwiecień 2019
    rem licencja public domain
    rem
    function count_tail(a as object, optional n as integer) as integer
      if ismissing(n) then
        n = ubound(a, 2)
      elseif n = 0 then goto tu
      elseif n > ubound(a, 2) then      
        n = ubound(a,2)
      endif
      do while isempty(a(1,n))
        n = n-1          
        if n = 0 then
tu:       count_tail = 0
          exit function
        end if
      loop
      v = a(1,n)
      k = n
      do while (a(1,k) = v)
        k = k-1
        if k = 0 then exit do
      loop
      count_tail = n-k
    end function
No i trzeba mieć na uwadze aby pusta komórka nie pojawiła się gdzieś w środku ...
LibreOffice 7.4.6 (preferowany) oraz OpenOffice 4.1.6. Widows 10
OpenOffice 4.1.3. oraz Libre 4.2.5.2 Windows XP
Jan_J
Posty: 4558
Rejestracja: pt maja 22, 2009 1:20 pm
Lokalizacja: Wrocław

Re: Wyodrebnianie ilosci tych samych liczb z konca ciagu.

Post autor: Jan_J »

Dzięki, słusznie.

Ja bym zamiast skoku (do wnętrza ciała pętli! żeby opuścić funkcję! co na to Edsger W. D.?) przekazał wynik 0 i uciekł.

Kolejna zmiana z warunku = na <= zabezpieczy przed skutkiem przekazania ujemnej wartości n.

Zaś pierwsza pętla while powinna mieć zastosowanie tylko w sytuacji domyślnego n.

I wróciłem do typu array, bardziej wyspecjalizowanego niż object, który mi się przypadkiem zaplątał podczas testów.

Więc jeszcze raz składam w całość kolejny wariant

Kod: Zaznacz cały

rem
rem zlicza liczbę jednakowych wyrazów na końcu ciągu a
rem opracował zespół forum.openoffice.org/pl, kwiecień 2019
rem licencja public domain
rem
function count_tail(a as array, optional n as integer) as integer
	if ismissing(n) then
		n = ubound(a, 2)
		do while isempty(a(1,n))
			n = n-1         
			if n = 0 then
				count_tail = 0
				exit function
			end if
		loop
	elseif n <= 0 then
		count_tail = 0
		exit function
	elseif n > ubound(a, 2) then     
		n = ubound(a,2)
	endif
	v = a(1,n)
	k = n
	do while (a(1,k) = v)
		k = k-1
		if k = 0 then exit do
	loop
	count_tail = n-k
end function
JJ
LO (7.6|24.2) ∙ Python (3.12|3.10) ∙ Unicode 15 ∙ LᴬTEX 2ε ∙ XML ∙ Unix tools ∙ Linux (Rocky|CentOS)
ODPOWIEDZ