|
[ vladab @ 01.03.2005. 23:12 ] @
Mislim da ti krljanje ne gine. Moras da gledas tezinu cifre i po tome da odredjujes da li su to stotine, hiljade ili milioni, a trebalo bi da povedes racuna o jednini i mnozini - znaci par veelikih case naredbi, sem ako ne nadjes da je to neko vec odradio. :O)
[ IgLo @ 02.03.2005. 01:12 ] @
Cao,...
Ovih dana dokolicarim malo pa sam se bacio na humanitarni rad, evo i za tebe jedna procedurica...  mislim da sam je dobro odratio, ali testiraj je malo pre nego sto je upotrebis (zavrsio sam je u 2:00 ujutru, pa ces me valjda razumeti, ako nesto nije uredu
Znaci tvoju cifru konvertuj u string, pa prosledi funkciji (radi do 999999999999,99 - valjda firma nece nista u bilionima racunati  ). U njoj samo podesi konstante kako tebi odgovaraju, ubaci YU slova ako ti trebaju i to je to. Eventualno je mozes prepraviti da kao parametar prima Float. I proveri da li sam sve nazive cifri dobro napisao.
Sada mi je palo na pamet,... moglo bi se jos doratiti da ne ispisuje "jedna hiljada" vec "hiljadu" i umesto "jedan milon", "milion", ali to su vec finese... ostavljam ih tebi...
Code:
Function TForm1.CurencyToStr (S : String) : String;
Const
Separator = ',';
StotiFormat = ' i %s/100';
Jedinice : Array [0..1, 1..19] Of String =
(('jedna', 'dve', 'tri', 'cetiri', 'pet',
'sest', 'sedam', 'osam', 'devet', 'deset',
'jedanaest', 'dvanaest', 'trinaest', 'cetrnajest', 'petnaest',
'sesnaest', 'sedamnaest', 'osamnaest', 'devetnaest'),
('jedan', 'dva', 'tri', 'cetiri', 'pet',
'sest', 'sedam', 'osam', 'devet', 'deset',
'jedanaest', 'dvanaest', 'trinaest', 'cetrnajest', 'petnaest',
'sesnaest', 'sedamnaest', 'osamnaest', 'devetnaest')
);
Desetice : Array [2..9] Of String =
('dvadeset', 'trideset', 'cetrdeset', 'pedeset',
'sezdeset', 'sedamdeset', 'osamdeset', 'devedeset');
Stotine : Array [0..9] Of String =
('', 'sto', 'dvesta', 'trista', 'cetirsto',
'petsto', 'sesto', 'sedamsto', 'osamsto', 'devetsto');
Prilozi : Array [1..4, 0..5] Of String =
((' dinar', '', 'a', 'a', 'a', 'a'),
('hiljad', 'a', 'e', 'e', 'e', 'a'),
('milion', '', 'a', 'a', 'a', 'a'),
('milijard', 'a', 'e', 'e', 'e', 'i')
);
Var
Stoti : String;
Trojka,
Temp : String;
X : Integer;
Begin
Stoti :='';
If Pos (Separator, S) > 0 Then
Begin
Stoti := Copy (S, Pos (Separator, S) + 1, Length (S));
S := Copy (S, 1, Pos (Separator, S) - 1);
// Ovde bi eventualno trebalo umesto secenja na dve decimale
// uraditi zaokruzivanje
If Length (Stoti) > 2 Then Stoti := Copy (Stoti, 1, 2);
End;
// Ne moze StrToInt jer je maxint 2147483647
If StrToFloat (S) = 0 Then
Result := 'nula'
Else
Begin
While Length (Stoti) < 2 Do Stoti := '0' + Stoti;
While Length (S) Mod 3 <> 0 Do S := '0' + S;
Result := '';
For X := 1 To 4 Do
Begin
Trojka := Copy (S, Length (S) - 2, 3);
Delete (S, Length (S) - 2, 3);
If Trojka = '' Then
Trojka := '000';
If Trojka <> '000' Then
Begin
If Trojka [2] In ['0', '1'] Then
Temp := Jedinice [X mod 2, StrToInt (Trojka [2] + Trojka [3])]
Else
Temp := Desetice [StrToInt (Trojka [2])] + Jedinice [X mod 2, StrToInt (Trojka [3])];
Temp := Stotine [StrToInt (Trojka [1])] + Temp;
If StrToInt (Trojka [2] + Trojka[3]) <= 5 Then
Temp := Temp + Prilozi [x, 0] + Prilozi [x, StrToInt (Trojka[2] + Trojka[3])]
Else
Temp := Temp + Prilozi [x, 0] + Prilozi [x, 5];
Result := Temp + Result;
End;
End;
End;
Result := Result + Format (StotiFormat, [Stoti]);
end;
Javi da li je to ono sto ti je trebalo.
Usput, odgovor za VladaB: Kada sam krenuo da je radim, mislio sam da ce biti par velikih Case-ova kao sto si spomenuo... ali evo bez ijednog
[ vladab @ 02.03.2005. 10:52 ] @
Stvarno lepo resenje! Ne verujem da bih se setio. :O)
[ Bojan Kopanja @ 02.03.2005. 19:05 ] @
Eh, sto vilom ove sa humanitarnog rada :D. Hvala ti, ovo je upravo to sto sam pitao, a i radi fantasticno, bar onoliko koliko sam ga probao.
Eto, koliko je bolje kad covek lepo pita, posto sam i ja imao na umu "brute force" nacin za resavanje ovog problema, tj. gomilu case naredbi :).
Hvala jos jednom!
[ Nemanja Avramović @ 03.03.2005. 19:57 ] @
ima greska kod 100
sve sto sam uradio je da sam stavio if petljicu tako da ako nema para - da ne ispisuje ono i %s/100
mada i dok to nisam uradio, sa 100 je zezalo
slika 1 predstavlja gresku, a slike 2 i 3 predstavljaju to da program u drugim situacijama lepo radi
[ Bojan Kopanja @ 03.03.2005. 22:12 ] @
Uh, to nisam ni probao, ali sam sada video da se ta gerska javlja izgleda gde god se desi u broju da stoji "100", znaci i ako je broj 15110023 na ovom deli "100" ce da pogresi...
Ma u svakom slucaju nista tragicno i ne resivo tako da nema problema ;).
[ Nemanja Avramović @ 03.03.2005. 22:50 ] @
pa bar postavi ovde resenje
[ johnnie @ 03.03.2005. 23:06 ] @
elegantna funkcija, nema sta...
A jel ima neko vise iskustva sa Apollo VCL 5.2 ili njegov help file?
Imam i 6.1 ali je evaluation, pa mi ne vrsi posao...
[ Bojan Kopanja @ 04.03.2005. 00:15 ] @
@ JaHvram
Pa nisam stigao da trazim za sada gresku u samoj f-ji, tako da sam ovo resio iz QuickReporta jednom If naredbom na polju za ispis ukupne cene slovima, a kad uhvatim malo vremena, potrazicu bug pa cu javiti.
Ovo sto sam odradio za sada radi super, samo pod pretpostavkom da nema bug na jos nekim brojevima... Ako ima, onda ce biti svasta lol...
Poz!
[ IgLo @ 04.03.2005. 11:47 ] @
U pravu ste,...bilo je par greskica, ali ne samo kada je u pitanju 100, vec i 200, 300 ... 900. Izvinjavam se  Evo prepravljene funkcije. Malo je izmenjena struktura podataka, dodat jedan "Else ... If.... Then..." i par indeksa je promenjeno. Resen je i problem kada se prosledi nula (sada ispisuje rec "dinara" i ispisue decimale).
Code:
Function CurencyToStr (S : String) : String;
Const
Separator = ',';
StotiFormat = ' i %s/100';
Jedinice : Array [0..1, 0..19] Of String =
(('', 'jedna', 'dve', 'tri', 'cetiri',
'pet', 'sest', 'sedam', 'osam', 'devet',
'deset', 'jedanaest', 'dvanaest', 'trinaest', 'cetrnajest',
'petnaest', 'sesnaest', 'sedamnaest', 'osamnaest', 'devetnaest'),
('', 'jedan', 'dva', 'tri', 'cetiri',
'pet', 'sest', 'sedam', 'osam', 'devet',
'deset', 'jedanaest', 'dvanaest', 'trinaest', 'cetrnajest',
'petnaest', 'sesnaest', 'sedamnaest', 'osamnaest', 'devetnaest')
);
Desetice : Array [2..9] Of String =
('dvadeset', 'trideset', 'cetrdeset', 'pedeset',
'sezdeset', 'sedamdeset', 'osamdeset', 'devedeset');
Stotine : Array [0..9] Of String =
('', 'sto', 'dvesta', 'trista', 'cetirsto',
'petsto', 'sesto', 'sedamsto', 'osamsto', 'devetsto');
Prilozi : Array [1..4, -1..5] Of String =
((' dinar', 'a', '', 'a', 'a', 'a', 'a'),
('hiljad', 'a', 'a', 'e', 'e', 'e', 'a'),
('milion', 'a', '', 'a', 'a', 'a', 'a'),
('milijard', 'i', 'a', 'e', 'e', 'e', 'i')
);
Var
Stoti : String;
Trojka,
Temp : String;
X : Integer;
Begin
Stoti :='';
If Pos (Separator, S) > 0 Then
Begin
Stoti := Copy (S, Pos (Separator, S) + 1, Length (S));
S := Copy (S, 1, Pos (Separator, S) - 1);
// Ovde bi eventualno trebalo umesto secenja na dve decimale
// uraditi zaokruzivanje
If Length (Stoti) > 2 Then Stoti := Copy (Stoti, 1, 2);
End;
While Length (Stoti) < 2 Do Stoti := '0' + Stoti;
// Ne moze StrToInt jer je maxint 2147483647
If StrToFloat (S) = 0 Then
Result := 'nula dinara'
Else
Begin
While Length (S) Mod 3 <> 0 Do S := '0' + S;
Result := '';
For X := 1 To 4 Do
Begin
Trojka := Copy (S, Length (S) - 2, 3);
Delete (S, Length (S) - 2, 3);
If Trojka = '' Then
Trojka := '000';
If Trojka <> '000' Then
Begin
If Trojka [2] In ['0', '1'] Then
Temp := Jedinice [X mod 2, StrToInt (Trojka [2] + Trojka [3])]
Else
Temp := Desetice [StrToInt (Trojka [2])] + Jedinice [X mod 2, StrToInt (Trojka [3])];
Temp := Stotine [StrToInt (Trojka [1])] + Temp;
If StrToInt (Trojka [2] + Trojka[3]) <= 5 Then
Temp := Temp + Prilozi [x, -1] + Prilozi [x, StrToInt (Trojka[2] + Trojka[3])]
Else
Temp := Temp + Prilozi [x, -1] + Prilozi [x, 5];
Result := Temp + Result;
End
Else
If X = 1 Then
Result := Result + ' dinara';
End;
End;
Result := Result + Format (StotiFormat, [Stoti]);
end;
Ako bude jos gresaka, javite, pa cu da ispravljam 
[ IgLo @ 04.03.2005. 11:54 ] @
Zaboravih da kazem... onu ispravku da ne ispisuje pare kada ih nema nisam ubacio, jer koliko znam na svim zvanicnim fakturama, kada nema para stavlja se "i 00/100" jer ako ne stavis, neko moze da dopise i da ti ukrade max 99 para  Mislim smesno izgleda, ali u finansijama mora sve da se slaze, zar ne 
[ Bojan Kopanja @ 04.03.2005. 15:16 ] @
Cool, thax na ispravljenoj funkciji, a što se tiče slučaja kada je 0 para u pitanju, tu i treba, kao što si i pretpostavio, da ispisuje 00/100, tako da tu nema šta da se ispravlja.
[ Nemanja Avramović @ 04.03.2005. 20:16 ] @
znam da treba 00/100, ovo sam bezze radio, cisto da vidim jel' umem da ubacim jedan if
lol ;)
[ Bojan Kopanja @ 27.03.2005. 09:08 ] @
Nikako da napisem ovde za jos jedan bagic... Naime kada je broj recimo 125,9 dinara program ce ispisati "stodvadesetpet dinara i 09/100" tako da treba samo dodati proveru tamo kada se odsece broj iza zareza:
Code: If Length (Stoti) < 2 Then Stoti := Stoti + '0';
Eto, mislim da sada radi fantasticno i da je sve sto se tice bagova sredjeno  .
[ IgLo @ 27.03.2005. 12:08 ] @
Drago mi je da je proradilo kako teba  Hvala na ispravci, necu ovde postovati ponovo ceo kod, kome treba znace da ispravi sam 
[ Bojan Kopanja @ 27.03.2005. 12:45 ] @
NP  , hvala tebi na prvobitnom kodu! Ovo su sada samo finese  .
[ mzarko @ 27.05.2005. 21:38 ] @
Posto slovima ispisuje maksimalno milijarde, i kada se u nastavku iza 12 brojeva upise neki 13-ti drugi broj koji je razlicit od 12-og onda recima ispisuje netacan broj. npr.
(ispravno)
111111111111
stojedanaestmilijardistojedanaestmilionastojedanaesthiljadastojedanaest dinara i 00/100
(neispravno)
1111111111119
stojedanaestmilijardistojedanaestmilionastojedanaesthiljadastodevetnaest dinara i 00/100
Mozda ne bi bilo lose da se i ovo otkloni, jer mozda neko barata i sa ovolikim ciframa
[ IgLo @ 28.05.2005. 11:18 ] @
Nemoj me 100% drzati za rac, ali koliko se secam ovo ogranicenje sam stavio jer mi se gramatika za vece brojeve ne uklapa u algoritam. Ako budem imao vremena ovih dana da to malo pogledam, mozda i doradim, ali nista ne obecavam. 
[ marcha @ 17.05.2006. 11:16 ] @
Igore svaka cast za ovaj cod, ja sam ga samo jos malo sredjivao...
1. da f-ja ne bi zavisila od LocalSettingsa izbacio sam seprator i promenio nacin pozivanja
2. da ne ulazi u petlju for x:=1 to 4 kad za tim nema potrebe (nula dinara i nesto para)
3. ispis negativne vrednosti (minus pet dinara 01/100)
Code:
function CurrencyToSerbian(const Value: extended): string;
const
MaxVal = 999999999999;
sZeroValue = 'nula dinara';
StotiFormat = ' i %2.0f/100';
Jedinice: array [0..1, 0..19] of string =
(('', 'jedna', 'dve', 'tri', 'cetiri',
'pet', 'sest', 'sedam', 'osam', 'devet',
'deset', 'jedanaest', 'dvanaest', 'trinaest', 'cetrnajest',
'petnaest', 'sesnaest', 'sedamnaest', 'osamnaest', 'devetnaest'),
('', 'jedan', 'dva', 'tri', 'cetiri',
'pet', 'sest', 'sedam', 'osam', 'devet',
'deset', 'jedanaest', 'dvanaest', 'trinaest', 'cetrnajest',
'petnaest', 'sesnaest', 'sedamnaest', 'osamnaest', 'devetnaest')
);
Desetice: array [2..9] of string =
('dvadeset', 'trideset', 'cetrdeset', 'pedeset',
'sezdeset', 'sedamdeset', 'osamdeset', 'devedeset');
Stotine: array [0..9] of string =
('', 'sto', 'dvesta', 'trista', 'cetirsto',
'petsto', 'sesto', 'sedamsto', 'osamsto', 'devetsto');
Prilozi: array [1..4, -1..5] of string =
((' dinar', 'a', '', 'a', 'a', 'a', 'a'),
('hiljad', 'a', 'a', 'e', 'e', 'e', 'a'),
('milion', 'a', '', 'a', 'a', 'a', 'a'),
('milijard', 'i', 'a', 'e', 'e', 'e', 'i')
);
SignPrefix: array [boolean] of string = ('', 'minus ');
var
s, sStoti: string;
Trojka, Temp: string;
X: integer;
eCeo, eStoti: extended;
begin
Result := '';
if Value = 0 then
begin
Result := sZeroValue;
eStoti := 0;
end
else
begin
eCeo := Int(Abs(Value));
if eCeo > MaxVal then
Exit;
eStoti := Abs(Frac(Value)) * 100;
if eCeo = 0 then
Result := sZeroValue
else
begin
S := FloatToStr(eCeo);
while Length(S) mod 3 <> 0 do
S := '0' + S;
for X := 1 to 4 do
begin
Trojka := Copy(S, Length(S) - 2, 3);
Delete(S, Length(S) - 2, 3);
if Trojka = '' then
Trojka := '000';
if Trojka <> '000' then
begin
if Trojka[2] in ['0', '1'] then
Temp := Jedinice[X mod 2, StrToInt(Trojka[2] + Trojka[3])]
else
Temp := Desetice[StrToInt(Trojka[2])] +
Jedinice[X mod 2, StrToInt(Trojka[3])];
Temp := Stotine[StrToInt(Trojka[1])] + Temp;
if StrToInt(Trojka[2] + Trojka[3]) <= 5 then
Temp := Temp + Prilozi[x, -1] +
Prilozi[x, StrToInt(Trojka[2] + Trojka[3])]
else
Temp := Temp + Prilozi[x, -1] + Prilozi[x, 5];
Result := Temp + Result;
end;
end;
end;
end;
sStoti := Format(StotiFormat, [eStoti]);
Result := SignPrefix[(Value < 0)] + Result + sStoti;
end;
[ _deran_ @ 20.05.2006. 20:31 ] @
Copyright (C) 2001-2025 by www.elitesecurity.org. All rights reserved.
|