[ Bojan Kopanja @ 01.03.2005. 22:09 ] @
Pošto brzom pretragom foruma nisam uspeo da nađem ništa što bi mo pomoglo moram da vas ipak lično pitam .

Interesuje me kako moguda prebacim neki broj u slova, tj. da mi program napiše ako imam 1253,00 jednahiljadadvestotinepedesettri 00/00 ( već pogađate, radi se o ispisivanju nekih računa ).

Pošto ovo nisam uspeo sam da razradim ( u frci sam oko drugih stvari vezanih za sličnu problematiku ), interesuje me da li je neko već uspeo da reši ovo i da li je voljan da podeli isto sa ostalima .

Hvala unepred!
[ 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 ] @
Ima jedna komponenta...
http://www.torry.net/vcl/vcltools/unitsconversion/bconvert.zip