Július Pastierik / 04. 05. 2006, 00:00
V dnešnom dieli seriálu o programovaní makier v OpenOffice.org si nielen zlepšíme makro pre prevod čísla na text, ale zároveň si ukážeme, ako ho môžeme volať tými najrôznejšími spôsobmi.
Na úvod si pripomeňme, že minule sme si naprogramovali makro pre prevod čísla na text s tým, že sme zatiaľ neuvažovali o tzv. finančných číslach, t.j. tvare, keď sa číslovka jedna vypisuje aj pri stovkách či iných rádoch (jednosto, jedentisíc, …). Toto však v mnohých prípadoch nevyhovuje a preto si uvedieme teraz makro, v ktorom je tento prípad ošetrený. Pochopiteľne, makro upravíme tak, aby sme mohli dostať obidva požadované tvary. Za týmto účelom pridáme do funkcie „daj_slovne“ druhý – nepovinný parameter, pomocou ktorého budeme určovať typ výsledku. Vlastné makro potom môže vyzerať takto:
function daj_slovne(cislo as Long, optional financne as boolean) as string
dim rad as integer ' 1 – tisíc, 2 – milion, 3 – miliarda
dim slovne as string
dim pom_financne as boolean
dim analyza as long
if not IsMissing(financne) then ' Parameter typu výsledku je zadaný
pom_financne=financne
else ' Parameter nie je zadaný
pom_financne=FALSE ' štandardne nebudeme prevádzať na finančné číslo
endif
slovne=""
if cislo=0 then
' Osobitne musíme ošetriť číslo „nula“
slovne="nula"
else
rad=0
do while cislo<>0
' z čísla vyberieme posledné tri číslice
analyza=cislo mod 1000
' ktoré prevedieme na text
slovne=slovne_stovky(analyza, rad)+slovne
' číslo zmenšíme o už spracovanú časť
cislo=int(cislo/1000)
' a pridáme text rádu, ktorý budeme spracovávať v ďalšom kroku cyklu
if cislo<>0 then
rad=rad+1
slovne=slovne_rady(cislo mod 1000, rad)+slovne
endif
loop
if pom_financne then ' Úprava v prípade, že píšeme "finančné" číslovky
' Úprava výsledku, ak chceme finančné číslo
if (analyza>=100) and (analyza<=199) then
' úprava výsledku pre stovky
slovne="jedno"+slovne ' jednosto...
endif
if (analyza=1) and (rad=0) then
' úprava výsledku, ak sme prevádzali na text číslo jedna, lebo
' číslovka "jeden" sa skloňuje, t.j. vo financiách sa píše "jedna koruna".
slovne="jedna"
endif
if (analyza=1) and (rad>0) then
' úprava výsledku pre ostatné rády
select case rad
case 1, 2, 4, 6, 8
slovne="jeden"+slovne ' jedentisíc, jedenmilión, …
case 3, 5, 7, 9
slovne="jedna"+slovne ' jednamilarda, …
end select
endif
endif
endif
daj_slovne=slovne
end function
Teraz si ukážeme, ako budeme toto makro volať tými najrôznejšími spôsobmi. Podobne, ako sme to urobili pri makrách pre formátovanie textu, aj teraz si rozdelíme podprogramy do rôznych modulov. Už naprogramované funkcie uložíme do modulu „ Cislo_Slovom“ a nasledujúce podprogramy do modulu „Module1“ v zložke „Standart“. Robíme to z toho dôvodu, že pri volaní makier v Calcu je potrebné, aby sa tieto nachádzali v tejto zložke.
Pretože si teraz predstavujeme vstupnú funkciu „InputBox “, ukážeme si túto možnosť ako prvú s tým, že prevedené číslo ihneď vložíme do písaného textu:
sub Vloz_cislo_slovom
dim cislo_s as string
dim cislo as long
dim dokument, dispecer as object
dim argumenty(0) as new com.sun.star.beans.PropertyValue
cislo_s= inputbox("Zadajte celé číslo, ktoré chcete vložiť slovom:","Vloženie čísla slovom","")
if cislo_s<>"" then
' ak vôbec zadáme nejaký údaj, tak ho prevedieme na text
cislo=val(cislo_s)
dokument=ThisComponent.CurrentController.Frame
dispecer=createUnoService("com.sun.star.frame.DispatchHelper")
argumenty(0).Name = "Text"
argumenty(0).Value = Cislo_Slovom.Daj_Slovne(cislo)
' a vložíme ho do textu na aktuálnu pozíciu
dispecer.executeDispatch(dokument, ".uno:InsertText", "", 0, argumenty())
endif
end sub
Ešte praktickejšie riešenie je však také, že si napíšeme číslo priamo do dokumentu, označíme ho do bloku a napr. po stlačení niektorej klávesovej skratky, ku ktorej si priradíme nasledujúce makro ho ihneď prepíšeme jeho slovným znením:
sub Vloz_cislo_slovom
dim cislo_s as string
dim cislo as long
dim dokument, vyber, dispecer as object
dim argumenty(0) as new com.sun.star.beans.PropertyValue
dokument=thisComponent ' aktuálny dokument
vyber=dokument.getCurrentSelection() ' aktuálny vyber
' Ak je počet označených častí nenulový
if vyber.getCount()>0 then
' Vyberieme označený reťazec a orežeme ho o okrajové medzery
cislo_s=trim(vyber.getByIndex(0).getString())
if cislo_s<>"" then
' ak sme niečo označili, tak to prevedieme na text
cislo=val(cislo_s)
dokument=ThisComponent.CurrentController.Frame
dispecer=createUnoService("com.sun.star.frame.DispatchHelper")
argumenty(0).Name = "Text"
argumenty(0).Value = Cislo_Slovom.Daj_Slovne(cislo)
' a vložíme ho do textu na aktuálnu pozíciu
dispecer.executeDispatch(dokument, ".uno:InsertText", "", 0, argumenty())
endif
endif
end sub
Úplne najpohodlnejšie riešenie je však také, že napíšeme číslo do dokumentu a bez toho, aby sme ho označovali do bloku ho napr. po stlačení klávesovej skratky prepíšeme jeho slovným znením. Na tento účel však najprv musíme sami vyhľadať a označiť posledne vložené slovo pomocou takejto funkcie:
function posledne_slovo (kurzor as object) as string
' funkcia vráti posledne napísané slovo a zároveň ho označí do bloku
dim poms as string
dim slovo as boolean
dim OddelovaceSlov as string
OddelovaceSlov=" "+chr(&HA0)+chr(&H09)+chr(&H0A)+chr(&H0D)
OddelovaceSlov=OddelovaceSlov+"-/.,!?;…"
OddelovaceSlov=OddelovaceSlov+"()[]{}"
poms=""
slovo=false
do while (not kurzor.isAtStartOfLine) and (not slovo)
' pokiaľ nie sme na začiatku riadku a nie sme ešte na začiatku slova
' tak sa presunieme o jeden znak doľava s tým, že označíme tento znak do bloku
kurzor.goleft(1,true)
' označené slovo si uložíme do pomocnej premennej
poms=kurzor.getstring
' ak sme našli oddeľovač slov, tak sme na začiatku slova
slovo=instr(OddelovaceSlov,left(poms,1))
loop
if slovo and (len(poms)>1) then
' ak sme boli na začiatku slova (a ak sme vôbec niečo označili)
' tak musíme tento oddeľujúci znak z nájdeného slova vylúčiť, t.j.
' vrátime sa o krok späť
kurzor.goright(1,true)
poms=kurzor.getstring
endif
posledne_slovo=poms
end function
Vlastné makro pre vloženie slovného znenia môže potom vyzerať takto:
sub Vloz_cislo_slovom
dim kurzor, doc as object
dim cislo as long
dim scislo as string
doc=ThisComponent.CurrentController
kurzor=doc.getViewCursor() ' Aktuálna pozícia kurzora
scislo=posledne_slovo(kurzor)
cislo=val(scislo)
if trim(str(cislo))=scislo then
scislo=Cislo_Slovom.Daj_Slovne(cislo)
kurzor.SetString(scislo) ' označené číslo prepíšeme jeho slovným znením
endif
kurzor.goright(len(scislo),false) ' nakoniec odznačíme blok (zostal označený aj po vložení textu)
end sub
Ako ste si mohli všimnúť, funkcia pre hľadanie posledného slova ukončí jeho hľadanie, ak narazí na nejaký znak, ktorý považujeme za oddeľovač slov a preto musíme procedúru „Vloz_cislo_slovom“ volať ihneď po napísaní príslušného čísla bez toho, aby sme za ním zadali čo i len medzeru.
Nakoniec si naprogramujeme funkciu pre vloženie slovného znenia čísla v module Calc. Pretože niekedy požadujeme, aby vložené slovo začínalo veľkým písmenom, vylepšíme ju aj o takýto nepovinný paramater:
function Slovom(Cislo as Long, optional Financne, optional Velke)
dim nazov as string
dim pom_fin, pom_velke as boolean
' štandardne budeme predpokladať, že chceme finančné číslo
pom_fin=TRUE
if not IsMissing(Financne) then ' Parameter je zadaný
if TypeName(Financne)="String" then
' ak je vstupná hodnota logická, Calc ju odovzdá ako reťazec „true“ alebo „false“
if uCase(Financne)="TRUE" or uCase(Financne)="FALSE" then
pom_fin=Financne
endif
endif
endif
' štandardne budeme predpokladať, že chceme začínať veľkým písmenom
pom_velke=TRUE
if not IsMissing(Velke) then ' Parameter je zadaný
if TypeName(Velke)="String" then
if uCase(Velke)="TRUE" or uCase(Velke)="FALSE" then
pom_velke=Velke
endif
endif
endif
' číslo prevedieme na text
nazov=Cislo_Slovom.Daj_Slovne(cislo,pom_fin)
if pom_velke then
' a ak chceme prvé písmeno veľké, tak to zmeníme
nazov=uCase(left(nazov,1))+right(nazov,len(nazov)-1)
endif
Slovom=nazov
end function
Pri vlastnom volaní tejto funkcie si musíme uvedomiť, že nepovinné parametre sa „dopĺňajú“ zľava doprava, t.j. ak zadať tretí parameter „Velke“, musíme zadať aj druhý parameter „Financne“. Jednotlivé možnosti si však podrobnejšie preskúmajte ako domácu úlohu.
Skončili sme tretiu sériu nášho seriálu o programovaní makier v OpenOffice.org. Teraz môžete protestovať, že sme ešte neprebrali poslednú možnosť interaktívnych vstupov – dialógy. Vzhľadom na rozsah tejto problematiky im však budeme venovať celú nasledujúcu sériu článkov. Štvrtú sériu začneme, ako inak, makrami pre vkladanie nezalomiteľnej medzery za jednoznakové predložky s tým, že rozšírime možnosti OpenOffice.org o ich automatické vkladanie už počas písania (podobne, ako to majú konkurenčné produkty) a navyše do makra postupne zabudujeme možnosť vkladania „pružnej“ nezalomiteľnej medzery, čo v súčasnosti nedokážu ani najznámejšie platené kancelárske programy.
Pre všetkých záujemcov sme zároveň pripravili PDF verziu práve ukončenej tretej časti seriálu o programovaní makier v OpenOffice.org: makra_v_ooo_3.pdf (378kB, MD5 kontrolný súčet – 228D7C86E82E9173CCD131BA912A2786). Ako prílohy sú na príslušných stranách priamo v ňom vložené aj zdrojové texty makier v TXT formáte.
Copyright © 2002 - 2013 inet.sk, s. r. o. | Všetky práva vyhradené | Neprešlo jazykovou úpravou | ISSN 1336-1899
Využívame kvalitný webhosting za rozumnú cenu od Inet.sk