Basic - dane na wejście, dane "ze środka" i wyjście funkcji własnej. [SOLVED]

Użytkowanie arkusza kalkulacyjnego
AdamTko
Posty: 32
Rejestracja: pn maja 28, 2012 2:07 pm

Basic - dane na wejście, dane "ze środka" i wyjście funkcji własnej. [SOLVED]

Post autor: AdamTko »

Ponownie kilka pytań do mądrzejszych.

Buduję dość złożoną w sensie ilości danych na wejściu funkcję. Aktualnie podaję na wejście 23 komórki. Zatem mam definicję funkcji w postaci Function PPS (a1, a2, a3....a23) i wewnątrz tej funkcji prowadzę sobie obliczenia. I teraz pytania.

1. Ponieważ dane do przesłania do funkcji są w kilku rządkach arkusza, jedna komórka po drugiej, to chciałbym wywołać funkcję z argumentami jako zakres, czyli formuła = PPS (B1:B16; C1:C4; D10:D13) lub jakaś inna technika - bardzo by mi to ułatwiło zadanie, zamiast klikania 23 komórek i średników. Zwłaszcza, że te czynność będę musiał wykonać wiele razy.

2. Funkcja wylicza dla mnie kilka parametrów pośrednich, a na ich podstawie wynik finalny, który zwraca do arkusza. A czy jest możliwość, by mi zwracała więcej niż 1 wynik? Np ten finalny i wielkości/zmienne pośrednie?

3. J.w. tylko niekoniecznie na wyjściu funkcji. Alternatywnie mógłbym wypełniać określone komórki arkusza. Da się?

4. Czy da się zdefiniować wewnątrz własnej funkcji inną funkcję lub... podfunkcję czy cóś?
Ostatnio zmieniony pn gru 19, 2022 10:42 am przez AdamTko, łącznie zmieniany 1 raz.
LO, PA, W7
Jan_J
Posty: 4583
Rejestracja: pt maja 22, 2009 1:20 pm
Lokalizacja: Wrocław

Re: Basic - dane na wejście, dane "ze środka" i wyjście funkcji własnej.

Post autor: Jan_J »

Na podstawowe pytania być może wystarczą odpowiedzi z dokumentacji:
https://wiki.openoffice.org/wiki/Docume ... ASIC_Guide
https://wiki.documentfoundation.org/Doc ... ASIC_Guide

Ad 1. Da się. Funkcja otrzyma jedn- albo dwuwymiarową tablicę typu Variant z danymi pobranymi z obszarów.
Ale jeśli chcesz połączyć argumenty w jedną tablicę np. by a1;a2;a3 albo a1:a3 albo a1:a2~a3 były różnymi wariantami określenia parametrów dla jednej funkcji, to lekko nie będzie.

Ad 2. Da się. Patrz niżej:

Kod: Zaznacz cały

function qq() as array
dim q(2) as integer
q(0) = 1
q(1) = 2
qq = q
end function

function rr()
  rr = qq()
end function
Ad 3. Da się, ale tracisz elegancję funkcji. Pamiętaj, że funkcja nie otrzymuje żadnej informacji o adresach komórek, tylko wartości do przetworzenia. Do operowania na arkuszu służą makra (sub) a nie funkcje (function).

Ad 4. W Basicu się nie da, ale możesz wywoływać jedną funkcję z innej. Patrz przykład wyżej.

Basic jest przestarzałym językiem, trzyma się tylko dzięki tradycji (VBA) oraz integracji interpretera z oprogramowaniem.
JJ
LO (24.2) ∙ Python (3.12|3.10) ∙ Unicode 15 ∙ LᴬTEX 2ε ∙ XML ∙ Unix tools ∙ Linux (Rocky|CentOS)
Awatar użytkownika
Rafkus
Posty: 527
Rejestracja: czw kwie 12, 2018 10:26 pm

Re: Basic - dane na wejście, dane "ze środka" i wyjście funkcji własnej.

Post autor: Rafkus »

Ad 1. Przykładowa funkcja odczytująca wartości dla jednego zakresu:

Kod: Zaznacz cały

function PPS(dane as variant )as variant
dim wynik(1) as variant
  if IsArray(dane) then         'czy dane są tablicą
    print "pierwszy wiersz zaczyna się od nr: " & LBound (dane,1)	'prawdopodobnie zawsze zaczyna liczyć od 1
    print "ostatni wiersz ma numer:" & UBound (dane,1)
    print "pierwsza kolumna zaczyna się od nr: " & LBound (dane,2)	'prawdopodobnie zawsze zaczyna liczyć od 1
    print "ostatni wiersz ma numer:" & UBound (dane,2)    
    print "twój zakres danych ma " & UBound (dane,1) & " wiersz-y oraz " & UBound (dane,2) & " kolumn."
    
    'odczytaj elementy zakresu:
    for i = 1 to UBound(dane,1)
      for j = 1 to UBound(dane,2)
        print dane(i, j)    
      next j
    next i
    
    'Stwórz wynik, którym tutaj będzie wymiar zakresu
    wynik(0) = "w = " & UBound(dane,1)
    wynik(1) = "k = " & UBound(dane,2)
    PPS = wynik    
  else
    PPS = "to nie tablica, twoja zmienna to: "   & dane
  endif  
end function
LibreOffice 7.4.6 (preferowany) oraz OpenOffice 4.1.6. Widows 10
OpenOffice 4.1.3. oraz Libre 4.2.5.2 Windows XP
AdamTko
Posty: 32
Rejestracja: pn maja 28, 2012 2:07 pm

Re: Basic - dane na wejście, dane "ze środka" i wyjście funkcji własnej.

Post autor: AdamTko »

Jan_J pisze: wt gru 13, 2022 3:58 pm Ad 1. Da się. Funkcja otrzyma jedn- albo dwuwymiarową tablicę typu Variant z danymi pobranymi z obszarów.
Ale jeśli chcesz połączyć argumenty w jedną tablicę np. by a1;a2;a3 albo a1:a3 albo a1:a2~a3 były różnymi wariantami określenia parametrów dla jednej funkcji, to lekko nie będzie.
Chcę tylko wygodnie wybrać komórki, tak jak do sumowania w calcu: =SUMA(F20:P20;F29:U29; A1:A5), trzy zakresy oddzielone średnikiem i już. Zamiast klikania w kolejne. Ale nie jest to jakieś kluczowe. Po prostu mniej szansy na missclicki.
Jan_J pisze: wt gru 13, 2022 3:58 pm Ad 2. Da się. Patrz niżej:

Kod: Zaznacz cały

function qq() as array
dim q(2) as integer
q(0) = 1
q(1) = 2
qq = q
end function
OK, ale jak przypisać komórce drugi wyraz tej macierzy? Proste przypisanie =gg() zwraca mi pierwszy (albo raczej zerowy) wyraz.
Jan_J pisze: wt gru 13, 2022 3:58 pm Ad 3. Da się, ale tracisz elegancję funkcji. Pamiętaj, że funkcja nie otrzymuje żadnej informacji o adresach komórek, tylko wartości do przetworzenia. Do operowania na arkuszu służą makra (sub) a nie funkcje (function).
W moim przypadku byłoby bardzo przydatne, by po prostu wpisywać w wybrane pola na szybko pośrednie wartości, wydaje mi się, że piekielnie ułatwiłoby mi to testowanie i wyłapywanie błędów własnych, które popełniam w obliczeniach. Z makrami obiecuję się także zapoznać, chociaż z jakiegoś nieznanego mi powodu czuję opór. :/
Jan_J pisze: wt gru 13, 2022 3:58 pm Ad 4. W Basicu się nie da, ale możesz wywoływać jedną funkcję z innej. Patrz przykład wyżej.

Basic jest przestarzałym językiem, trzyma się tylko dzięki tradycji (VBA) oraz integracji interpretera z oprogramowaniem.
Wydaje mi się, że w jednej z prób testowałem wywołanie odrębnie (nie wewnątrz) zdefiniowanej funkcji ale oczywiście spróbuje ponownie.

Janie, co do stron pomocy - jak najbardziej tam zaglądam, jednak nie zawsze potrafię odszukać jakiś adekwatny wpis i podpowiedź, a jeśli idzie o przestarzały Basic - ja też jestem modelem schyłkowym i mój resurs nie będzie się odnawiał. Mimo to zaczynam się z Pythonem zapoznawać i z C (bo arduino). I o ile samo programowanie sprawia mi przyjemność, nawet w najprostszych kwestiach, o tyle właśnie ta integracja, metody wywoływania i zwracania wartości do środowiska już mnie zwykle dołują.
LO, PA, W7
AdamTko
Posty: 32
Rejestracja: pn maja 28, 2012 2:07 pm

Re: Basic - dane na wejście, dane "ze środka" i wyjście funkcji własnej.

Post autor: AdamTko »

Rafkus pisze: wt gru 13, 2022 4:25 pm Ad 1. Przykładowa funkcja odczytująca wartości dla jednego zakresu:

Kod: Zaznacz cały

function PPS(dane as variant )as variant
end function
Dzięki. Jan również coś o typie variant pisał. Zapoznam się. Ale na potrzeby tego zagadnienia nad którym muszę pracować chyba mi zabraknie czasu na zgłębianie. Tym niemniej wrócę do tego za niedługo.

Dzięki za podpowiedź. :)
LO, PA, W7
Awatar użytkownika
Jermor
Posty: 2361
Rejestracja: sob paź 12, 2013 11:09 am
Kontakt:

Re: Basic - dane na wejście, dane "ze środka" i wyjście funkcji własnej.

Post autor: Jermor »

ad 4. Wydaje mi się, że można. Zobacz składnię instrukcji GOSUB.
Pomoc z Apache OpenOffice, bo w LIbreOffice ten temat jest częściowo po angielsku, częściowo po polsku.
Wywołuje podprogram oznaczony etykietą z innego podprogramu lub funkcji. Instrukcje umieszczone za etykietą są wykonywane aż do napotkania instrukcji Return. Następnie wykonywanie programu jest kontynuowane od instrukcji następującej bezpośrednio po instrukcji GoSub.
Składnia:
Zobacz Parametry
Parametry:
Sub/Function
blok instrukcji
Etykieta
blok instrukcji
GoSub Etykieta
Exit Sub/Function
Etykieta:
blok instrukcji
Return
End Sub/Function
Instrukcja GoSub służy do wywołania podprogramu oznaczonego etykietą z innego podprogramu lub funkcji. Nazwa etykiety musi być zakończona dwukropkiem (":").

Jeśli program napotka instrukcję Return, która nie była poprzedzona instrukcją GoSub, OpenOffice zwraca komunikat o błędzie. W celu upewnienia się, że program opuści procedurę (Sub) lub funkcję (Function), zanim napotka następną instrukcję Return, należy użyć instrukcji Exit Sub lub Exit Function.

Poniższy przykład przedstawia użycie instrukcji GoSub i Return. Dwukrotne uruchomienie sekcji programu powoduje obliczenie pierwiastka kwadratowego dwóch liczb wprowadzonych przez użytkownika.
Przykład:
Sub ExampleGoSub
dim iInputa as Single
dim iInputb as Single
dim iInputc as Single
iInputa = Int(InputBox$ "Wprowadź pierwszą liczbę: ","Wprowadzenie liczby"))
iInputb = Int(InputBox$ "Wprowadź drugą liczbę: ","Wprowadzenie liczby"))
iInputc=iInputa
GoSub SquareRoot
Print "Pierwiastek kwadratowy z ";iInputa;" wynosi ";iInputc
iInputc=iInputb
GoSub SquareRoot
Print "Pierwiastek kwadratowy z ";iInputb;" wynosi ";iInputc
Exit Sub
SquareRoot:
iInputc=sqr(iInputc)
Return
End Sub
AOO 4.1.15, LO 24.8.2 (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.
Awatar użytkownika
Jermor
Posty: 2361
Rejestracja: sob paź 12, 2013 11:09 am
Kontakt:

Re: Basic - dane na wejście, dane "ze środka" i wyjście funkcji własnej.

Post autor: Jermor »

Jeszcze odpowiedź do
AdamTko pisze: wt gru 13, 2022 5:00 pm OK, ale jak przypisać komórce drugi wyraz tej macierzy? Proste przypisanie =gg() zwraca mi pierwszy (albo raczej zerowy) wyraz.
Jeśli po wpisaniu funkcji zatwierdzisz ją jako funkcję tablicową (SHIFT+CTRL+ENTER), to otrzymasz wynik w postaci tablicy.
AOO 4.1.15, LO 24.8.2 (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.
Awatar użytkownika
Rafkus
Posty: 527
Rejestracja: czw kwie 12, 2018 10:26 pm

Re: Basic - dane na wejście, dane "ze środka" i wyjście funkcji własnej.

Post autor: Rafkus »

Jermor pisze: wt gru 13, 2022 6:36 pm ad 4. Wydaje mi się, że można. Zobacz składnię instrukcji ...
Łał, znowu pokazałeś mi coś nowego ale...

@ AdamTko przyjrzyj się przykładowi zaproponowanemu przez @Jan_J:
Jan_J pisze: wt gru 13, 2022 3:58 pm Ad 2. Da się. Patrz niżej:

Kod: Zaznacz cały

function qq() as array
dim q(2) as integer
q(0) = 1
q(1) = 2
qq = q
end function

function rr()
  rr = qq()
end function
Są zaprezentowane dwie funkcje i druga z nich (rr) wywołuje pierwszą (qq). Uważam że to rozwiązanie jest bardziej przejrzyste.
LibreOffice 7.4.6 (preferowany) oraz OpenOffice 4.1.6. Widows 10
OpenOffice 4.1.3. oraz Libre 4.2.5.2 Windows XP
Awatar użytkownika
Jermor
Posty: 2361
Rejestracja: sob paź 12, 2013 11:09 am
Kontakt:

Re: Basic - dane na wejście, dane "ze środka" i wyjście funkcji własnej.

Post autor: Jermor »

Ja tylko odpowiedziałem, że da się, a nie że trzeba to tak wykonać.
No i jeszcze wyjaśnienie. Na razie, zgodnie z opisami, pierwszy element każdego wymiaru tablicy przekazanej do funkcji jako parametr ma indeks=1. Teoretycznie można więc nie wyznaczać tej wartości (LBound()). Mądrzy ludzie piszą jednak, że ktoś kiedyś może zmienić ten algorytm, dopasowując go do zasady indeksowania od 0, więc lepiej to stosować, aby w przyszłości makra się nie wykładały.
No i tylko taka uwaga do przykładu @Jan_J. Deklaracja Dim q(2) tworzy wektor trzyelementowy, więc wywołanie funkcji metodą tablicową zwróci trzy wartości, ostatnią będzie 0.
AOO 4.1.15, LO 24.8.2 (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: 4583
Rejestracja: pt maja 22, 2009 1:20 pm
Lokalizacja: Wrocław

Re: Basic - dane na wejście, dane "ze środka" i wyjście funkcji własnej.

Post autor: Jan_J »

O używaniu <Ctrl+Shift+Enter> w przypadku wywoływania funkcji o wynikach typu array (czyli wektorowej) z formuły powinienem był napisać.

Co do Dim 2, racja, dziekuję.

Zaś GoSub bym unikał. To archaiczna konstrukcja typu skok. O ile dobrze rozumirm, słowo `subroutine` w dokumentacji użyte zostało w sensie `sekwencja instrukcji, do której można skoczyć`. W nowocześniejszym podejściu analogiczny efekt da się otrzymać robiąc wariantowe przypisania wyniku wewnątrz instrukcji strukturalnej. Na przykład

Kod: Zaznacz cały

function ff(x)
if x mod 2 = 0 then
  ff = "przez 2"
elseif x mod 3 = 0 then
  ff ="przez 3"
else
  ff =  "przez coś"
end if  
end function
JJ
LO (24.2) ∙ Python (3.12|3.10) ∙ Unicode 15 ∙ LᴬTEX 2ε ∙ XML ∙ Unix tools ∙ Linux (Rocky|CentOS)
AdamTko
Posty: 32
Rejestracja: pn maja 28, 2012 2:07 pm

Re: Basic - dane na wejście, dane "ze środka" i wyjście funkcji własnej.

Post autor: AdamTko »

Jermor pisze: wt gru 13, 2022 6:52 pm Jeśli po wpisaniu funkcji zatwierdzisz ją jako funkcję tablicową (SHIFT+CTRL+ENTER), to otrzymasz wynik w postaci tablicy.
Podziałało w sensie takim że w trzech kolejnych komórkach wpisały mi wyniki. Mogę ich swobodnie użyć. Dzięki.

Jednak najfajniej byłoby, żebym w jakiejś komórce mógł wpisać regułę odwołującą się do konkretnego elementu tej funkcji/macierzy.
czyli coś w stylu =$A$1*1_wyraz_funkcji_qq. I tego nie umiem. Chyba mam nieprawidłowe wyobrażenie macierzy w Calc.
LO, PA, W7
Awatar użytkownika
Rafkus
Posty: 527
Rejestracja: czw kwie 12, 2018 10:26 pm

Re: Basic - dane na wejście, dane "ze środka" i wyjście funkcji własnej.

Post autor: Rafkus »

Możesz odwołać się do jakiegoś konkretnego elementu z zestawu wyników przy pomocy dodatkowego parametru, np:

Kod: Zaznacz cały

function qq(optional wynik as integer) as variant
dim q(2) as integer
q(0) = 1
q(1) = 2

If IsMissing(wynik)  then	'jeśli nie podano parametru wynik
  qq = q
elseif wynik<0 OR wynik>2 then	'jeśli parametr wynik jest spoza przedziału 0..2 
  qq = "Zły parametr"
else 		'podaj wymaganą daną
  qq=q(wynik)
endif
end function
Funkcja ta teraz w zależności od od opcjonalnego parametru wynik może zwrócić:
  • wywołanie funkcji: qq() - otrzymasz wszystkie wyniki jeśli została ona zatwierdzona kombinacją klawiszy CTRL+SHIFT+ENTER
  • wywołanie funkcji: qq(44) - otrzymasz informację, że wpisano błędny parametr
  • wywołanie funkcji: qq(1) - z zestawu wyników otrzymasz jeden konkretny o wartości podanej w q(1)
UWAGA : Zmiana w kodzie AND na OR dla przypadku gdy parametr wynik ma być spoza podanego przedziału. Nie ma szansy aby ten parametr był jednocześnie mniejszy od 0 i większy od 2.
Ostatnio zmieniony śr gru 14, 2022 3:19 pm przez Rafkus, łącznie zmieniany 2 razy.
Powód: Zmiana w kodzie
LibreOffice 7.4.6 (preferowany) oraz OpenOffice 4.1.6. Widows 10
OpenOffice 4.1.3. oraz Libre 4.2.5.2 Windows XP
AdamTko
Posty: 32
Rejestracja: pn maja 28, 2012 2:07 pm

Re: Basic - dane na wejście, dane "ze środka" i wyjście funkcji własnej.

Post autor: AdamTko »

Rafkus, to jest dokładnie to o co biegało. Teraz muszę zastosować się do rad, które od Szanownych Kolegów otrzymałem. Oczywiście nie wszystko jest dla mnie jasne, jednak mając jakieś odniesienia duuużo łatwiej jest szukać odpowiedzi w wiki, pomocy i wszelkich innych źródłach.
LO, PA, W7
ODPOWIEDZ