Strona 1 z 1
Wartość bezwzględna z komórki
: śr gru 05, 2018 10:19 pm
autor: HKRWCK
Witam potrzebuję makra OO które z zaznaczonej komórki tworzy wartość bezwzględną (dodatnią z ujemnej).
Makro z Excel wygląda następująco:
ub Positive
Dim Cel As Range
For Each Cel In Selection
If IsNumeric(Cel.Value) Then
Cel.Value = Abs(Cel.Value)
End If
Next Cel
End Sub
Dziękuję za pomoc.
Re: Wartość bezwzględna z komórki
: śr gru 05, 2018 11:45 pm
autor: Jan_J
Andrew Pitonyak: Andrew Macro (
http://www.pitonyak.org/AndrewMacro.odt) oraz OpenOffice Macros Explained (
http://www.pitonyak.org/book/)
Warto czytać, zwłaszcza jeżeli jest to rodzaj zadania domowego (nie wiem czy jest).
A jeśli potrzebujesz nie do szkoły/na studia, tylko do własnej pracy: czy na pewno potrzebne jest aż makro? może wystarczy formuła (zwykła albo wektorowa) z użyciem funkcji abs / moduł.liczby?
Re: Wartość bezwzględna z komórki
: czw gru 06, 2018 9:17 am
autor: HKRWCK
Dzięki za odpowiedź. Potrzebuję do pracy, żeby sobie ją ułatwić. Chodzi o to że przycisk mam na wstążce, po którego przyciśnięciu zaznaczona wcześniej komórka zmienia się na dodatnią. Idealny byłby kod do wklejenia
Re: Wartość bezwzględna z komórki
: czw gru 06, 2018 12:05 pm
autor: Jan_J
No tak.
Załączam efekt smażenia. Ujmuje 3 przypadki: zaznaczone nic/pojedyncza komórka, albo blok komórek, albo zespół takich bloków.
W każdym z tych przypadków obiekt reprezentujący zaznaczenie ma w Calcu inny typ (A. Pitonyak,
http://www.pitonyak.org/OOME_3_0.pdf, rozdział 15.4).
Testowałem wszystkie przypadki.
Wywołujemy tylko funkcję Positive().
Kod: Zaznacz cały
' rem cell: uchwyt obiektu komórki; obiekt modyfikowany jest in situ
sub absCell(cell)
if cell.getType() = 1 then cell.setValue(abs(cell.getValue()))
end sub
' doc: uchwyt obiektu skoroszytu; adr: obiekt adresowy zakresu (to nie jest obiekt zaznaczenia!)
' modyfikacja obejmuje komórki z tego zakresu
sub absRange(doc, adr)
sheet = doc.Sheets.getByIndex(adr.Sheet)
for i = adr.startcolumn to adr.endcolumn
for j = adr.startrow to adr.endrow
absCell(sheet.getCellbyPosition(i,j))
next j
next i
end sub
' doc: uchwyt obiektu skoroszytu; rng: uchwyt obiektu złożonego zakresu (to nie jest adres ani lista adresów!)
' modyfikacja obejmuje komórki z wszystkich zakresów tego złożonego zakresu
sub absRanges(doc, rng)
n = rng.count
for i = 0 to n-1
absRange(doc, rng.RangeAddresses(i))
next i
end sub
' wywołujemy tylko to
sub Positive()
dim doc as object
dim sel as object
doc = thisComponent
sel = doc.CurrentController.getSelection()
if sel.supportsService("com.sun.star.sheet.SheetCell") then
absCell(sel)
elseif sel.supportsService("com.sun.star.sheet.SheetCellRange") then
absRange(doc, sel.getRangeAddress())
else rem sel.supportsService("com.sun.star.sheet.SheetCellRanges")
absRanges(doc, sel)
end if
end sub
W VBA Excela wygląda krócej, z kilku powodów:
* Excel udostępnia globalnie całą masę obiektów reprezentujących stan aplikacji. W Calcu jest większy porządek, m.in. aplikacja (Calc, np. zaznaczenie) jest odseparowana od danych (arkusze, komórki), a liczba zmiennych domyślnie dostępnych globalnie jest ograniczona.
* Excel pozwala unikać unikać jawnych pętli po zakresach tablic, na korzyść składni wektorowej albo pętli typu `for each` (płaska lista, a nie indeksowana tablica).
W Calcu też jest pętla `for each` i jakieś elementy wektoryzacji, ale ich nie znam zbyt dobrze. Tu jest jakaś szansa na usprawnienie. Na przykład, funkcję dla zespołu bloków da się przepisać do postaci
Kod: Zaznacz cały
sub absRanges(doc, rng)
for each adr in rng.RangeAddresses
absRange(doc, adr)
next adr
end sub
ale czy są gotowe środki, by zrobić podobnie pojedynczą pętlę `for each` dla trawersu wielopoziomowej/wielowymiarowej struktury komórka po komórce, to nie wiem.
Re: Wartość bezwzględna z komórki
: czw gru 06, 2018 10:03 pm
autor: HKRWCK
Dziękuję za podjęcie tematu jednak po uruchomieniu makra wyskakuje komunikat jak poniżej
Wystąpił błąd modułu Scripting Framework podczas wykonywania w języku Basic skryptu Standard.Module1.absRanges.
Wrong number of parameters!
Re: Wartość bezwzględna z komórki
: czw gru 06, 2018 10:41 pm
autor: Jan_J
Wywoływać należy tylko procedurę Positive().
Pozostałe makra są używane do realizacji czynności w szczególnych sytuacjach, tak by nie pisać analogicznego kodu wielokrotnie. Muszą one mieć podane parametry, które trzeba przygotować programowo. Przy próbie wywołania z przycisku albo formularza będą generować błąd, bo parametrów im nie przekazano.
Można by im nadać atrybut private, wtedy nie byłyby widoczne z zewnątrz modułu, ale o takie szczegóły nie dbam w szkicu.
Sprawdzałem poprawność działania na LibreOffice Calc 6.0 (Windows 10) oraz 5.3 (OpenSUSE).
Nie sądzę, by obsługa zaznaczeń w Apache OpenOffice była inna; gdyby tak było, raczej wiedziałbym o tym.
Re: Wartość bezwzględna z komórki
: pt gru 07, 2018 9:23 pm
autor: HKRWCK
Witam,
Niestety używając funkcji Positive również nie działa mi kod makra. Jeżeli można to proszę o umieszczenie gotowego kodu w załączonym pliku.
Będę wdzięczny.
Pozdrawiam.
Re: Wartość bezwzględna z komórki
: pt gru 07, 2018 10:32 pm
autor: Jan_J
Wpięte, w załączeniu.
W kolumnie i arkusza "grudzień_2018" makro nie zadziała, bo tam nie leżą dane liczbowe, tylko wyniki obliczeń przez formuły.
W innych miejscach działa, sprawdzałem wpisując liczby ujemne w różne miejsca.
W makrze (konkretnie w funkcji absCell) jest umieszczony warunek: jeżeli zawartość komórki jest typu liczbowego, to nałóż na nią moduł.
Formuła to inny przypadek. Można się pozbyć warunku, ale wtedy stracisz związki między danymi a wynikami. Głupio.
Lepiej napisać w formule =moduł.liczby(czegoś_co_się_wylicza_a_co_może_być_ujemne).
Dlatego pytałem: czy nie lepiej formułą. Moim zdaniem, jeśli chcemy urwać minus z obliczeń dawanych przez formułę, to tylko formułą.
Jaką konkretnie decyzję podjąć? to zależy od logiki Twoich obliczeń. Żeby sobie pomóc, a nie nabałaganić.
Re: Wartość bezwzględna z komórki
: pt gru 07, 2018 10:38 pm
autor: HKRWCK
Czy nie można oderwać obliczeń danej formuły z liczbą ujemną i zastąpić ją modułem?
Re: Wartość bezwzględna z komórki
: pt gru 07, 2018 10:49 pm
autor: Jan_J
// sorry, użyłem [edit] zamiast [reply]; poprawiam się ;;
Można. Taki wariant
Kod: Zaznacz cały
sub absCell(cell)
cell.setValue(abs(cell.getValue()))
end sub
tak zrobi. Zyskasz dodatniość, stracisz formułę. Zaś próba wywołania na komórce z tekstem spowoduje wpisanie zera i utratę tekstu.
O wiele mądrzej jest zmienić formułę obliczającą. Zamiast
użyć
o tym pisałem na początku, a i wyżej także. No i policzy się wtedy `samo`, bez wciskania przycisku.
Re: Wartość bezwzględna z komórki
: pt gru 07, 2018 10:58 pm
autor: HKRWCK
Możesz mi to wrzucić w plik?
Re: Wartość bezwzględna z komórki
: pt gru 07, 2018 11:22 pm
autor: Jan_J
To nie jest programowanie, w sensie znajomości języka proceduralnego, tylko zwykła obsługa arkusza kalkulacyjnego.
Jeżeli zmodyfikujesz sobie formułę w kolumnie i wg mojego opisu, to będziesz mieć w niej same nieujemne wyniki, z formuł.
Z tym że ja nie wezmę odpowiedzialności za zgodność mojej propozycji z Twoim zamiarem.
Re: Wartość bezwzględna z komórki
: pt gru 07, 2018 11:36 pm
autor: HKRWCK
Chodzi mi o to że wartości ujemne są wpisywane wcześniej bo to zaległości klientów, natomiast powiedzmy na dzień dzisiejszy po wpłacie klienta wartość w komórce powinna być na +. Pomysł jest taki aby zaznaczoną komórkę przekształcało makro.
Re: Wartość bezwzględna z komórki
: sob gru 08, 2018 10:39 am
autor: Jan_J
Jeżeli wpłata jest rejestrowana w komórce, to wystarczy ją odjąć od zadłużenia. Sposób trochę zależy od organizacji danych, jeżeli rejestracja wpłat jest w osobnych kolumnach w kolejności ich dokonywania, to może wymagać wyszukania wpisu w tabeli (wyszukaj.pionowo).
Nie rozumiem dlaczego fakt dokonania wpłaty zmienia zadłużenie (np. -120) na wartość dodatnią (odp. 120) a nie na 0.
Ale może tak ma być, nie znam logiki tych obliczeń.