Ir al contenido



Foto

Numero en formato de letras


  • Por favor identifícate para responder
7 respuestas en este tema

#1 amell2020

amell2020

    Advanced Member

  • Miembros
  • PipPipPip
  • 338 mensajes
  • LocationEn un solo Lugar

Escrito 27 mayo 2019 - 09:42

Hola amigos que tal, cuanto tiempo, una vez mas aqui con delphi de nuevo, estoy tratando de haccer un  a funcion que pueda convertir monto de numero a Letras, ejemplo tengo en un edit el valor  de  1200 quiero que al convertirlo me lo lleve en letra "Mil Docientos Pesos". yo estoy tratando con esta funcion y  todo esta muy bien, solo tengo un error  con las cantidades de 1000 a 1999 que la escribe de esta forma "Un Mil Pesos" en vez de "Mil Pesos" .

 

dejare el codigo para que vena:


delphi
  1. Function CantidadEnLetra(curCantidad: Currency; MonNal: integer): String;
  2. var i: integer;
  3. Cantidad, Centavos: Currency;
  4. BloqueCero, NumeroBloques, Digito: Byte;
  5. PrimerDigito, SegundoDigito, TercerDigito: Byte;
  6. Resultado, Temp, strCentavos, Bloque: String;
  7. Unidades: Array[0..28] of String;
  8. Decenas: Array[0..8] of String;
  9. Centenas: Array[0..8] of String;
  10. begin
  11.  
  12. Unidades[0] := 'UN'; Unidades[1] := 'DOS'; Unidades[2] := 'TRES'; Unidades[3] := 'CUATRO';
  13. Unidades[4] := 'CINCO'; Unidades[5] := 'SEIS'; Unidades[6] := 'SIETE'; Unidades[7] := 'OCHO';
  14. Unidades[8] := 'NUEVE'; Unidades[9] := 'DIEZ'; Unidades[10] := 'ONCE'; Unidades[11] := 'DOCE';
  15. Unidades[12] := 'TRECE'; Unidades[13] := 'CATORCE'; Unidades[14] := 'QUINCE'; Unidades[15] := 'DIECISÉIS';
  16. Unidades[16] := 'DIECISIETE'; Unidades[17] := 'DIECIOCHO'; Unidades[18] := 'DIECINUEVE';
  17. Unidades[19] := 'VEINTE'; Unidades[20] := 'VEINTIUNO'; Unidades[21] := 'VEINTIDÓS';
  18. Unidades[22] := 'VEINTITRÉS'; Unidades[23] := 'VEINTICUATRO'; Unidades[24] := 'VEINTICINCO';
  19. Unidades[25] := 'VEINTISÉIS'; Unidades[26] := 'VEINTISIETE'; Unidades[27] := 'VEINTIOCHO'; Unidades[28] := 'VEINTINUEVE';
  20.  
  21. Decenas[0] := 'DIEZ'; Decenas[1] := 'VEINTE'; Decenas[2] := 'TREINTA'; Decenas[3] := 'CUARENTA';
  22. Decenas[4] := 'CINCUENTA'; Decenas[5] := 'SESENTA'; Decenas[6] := 'SETENTA'; Decenas[7] := 'OCHENTA'; Decenas[8] := 'NOVENTA';
  23.  
  24. Centenas[0] := 'CIENTO'; Centenas[1] := 'DOSCIENTOS'; Centenas[2] := 'TRESCIENTOS'; Centenas[3] := 'CUATROCIENTOS';
  25. Centenas[4] := 'QUINIENTOS'; Centenas[5] := 'SEISCIENTOS'; Centenas[6] := 'SETECIENTOS'; Centenas[7] := 'OCHOCIENTOS'; Centenas[8] := 'NOVECIENTOS';
  26.  
  27. Cantidad := Trunc(curCantidad);
  28. Centavos := (curCantidad - Cantidad) * 100;
  29. NumeroBloques := 1;
  30. Repeat
  31. PrimerDigito := 0;
  32. SegundoDigito := 0;
  33. TercerDigito := 0;
  34. Bloque := '';
  35. BloqueCero := 0;
  36. For i := 1 To 3 do begin
  37. Digito := Round(Cantidad) Mod 10;
  38. If Digito <> 0 Then begin
  39. Case i of
  40. 1: begin
  41. Bloque := ' ' + Unidades[Digito - 1];
  42. PrimerDigito := Digito;
  43. end; //case 1
  44. 2: begin
  45. If Digito <= 2 Then begin
  46. Bloque := ' ' + Unidades[(Digito * 10 + PrimerDigito - 1)];
  47. end Else begin
  48. If PrimerDigito <> 0 then
  49. Temp := ' Y' else Temp := '';
  50. Bloque := ' ' + Decenas[Digito - 1] + Temp + Bloque;
  51. End; //if
  52. SegundoDigito := Digito;
  53. end; //case 2
  54. 3: begin
  55. If (Digito = 1) and (PrimerDigito = 0) and (SegundoDigito = 0) then
  56. Temp := 'CIEN' else Temp := Centenas[Digito-1];
  57. Bloque := ' ' + Temp + Bloque;
  58. TercerDigito := Digito;
  59. end; //case 3
  60. End; //case
  61. end Else begin
  62. BloqueCero := BloqueCero + 1;
  63. End; // If Digito <>0
  64. Cantidad := Int(Cantidad / 10);
  65. If Cantidad = 0 Then begin
  66. Break;
  67. End; // If Cantidad=0
  68. end; //for
  69. Case NumeroBloques of
  70. 1:
  71. Resultado := Bloque;
  72. 2: begin
  73. if BloqueCero = 3 then
  74. Temp := '' else Temp := ' MIL';
  75. Resultado := Bloque + Temp + Resultado;
  76. end; //case 2
  77. 3: begin
  78. If (PrimerDigito = 1) and (SegundoDigito = 0) and (TercerDigito = 0) then
  79. Temp := ' MILLON' else Temp := ' MILLONES';
  80. Resultado := Bloque + Temp + Resultado;
  81. end; //case 3
  82. End; //case
  83. NumeroBloques := NumeroBloques + 1;
  84. Until Cantidad = 0; //repeat
  85. case MonNal of
  86. 0: begin
  87. If curCantidad > 1 then
  88. Temp := ' CENTAVOS ' else Temp := ' CENTAVO ';
  89. CantidadEnLetra := Resultado + Temp;
  90.  
  91. end;
  92. 1: begin
  93. If curCantidad > 1 then
  94. Temp := ' PESOS ' else Temp := ' PESO ';
  95. if Centavos=0 then strCentavos := '' else strCentavos := 'CON '+CantidadEnLetra(Centavos, 0);
  96. CantidadEnLetra := '**' + Resultado + Temp + strCentavos+'**';
  97. end;
  98. 2: begin
  99. If curCantidad > 1 then
  100. Temp := ' DLLS ' else Temp := ' DOLAR ';
  101. if Centavos=0 then strCentavos := '' else strCentavos := 'CON '+CantidadEnLetra(Centavos, 0);
  102. CantidadEnLetra := '** ' + Resultado + Temp + strCentavos;
  103. end;
  104. end;

Estado pensando en  eliminar la cadena de string la primera y segunda letras si monto es = 1000 y menor de 1999.


  • 0

#2 escafandra

escafandra

    Advanced Member

  • Moderadores
  • PipPipPip
  • 3.837 mensajes
  • LocationMadrid - España

Escrito 27 mayo 2019 - 10:54

Aquí tienes varios ejemplos para hacer lo que pretendes: Pasaje de números a letras.

Saludos.
  • 0

#3 amell2020

amell2020

    Advanced Member

  • Miembros
  • PipPipPip
  • 338 mensajes
  • LocationEn un solo Lugar

Escrito 27 mayo 2019 - 02:39

Ya gracias Escafandra, lo resolví con con esto:


delphi
  1. StringReplace(CantidadEnLetra(edtmonto.Value, 1) , 'UN', '', [] );


  • 0

#4 santiago14

santiago14

    Advanced Member

  • Miembros
  • PipPipPip
  • 322 mensajes
  • LocationCerrillos - Salta - Argentina

Escrito 29 mayo 2019 - 05:27

Esto funciona muy bien, lo tengo desde hace años.


delphi
  1. unit Numero2Letras;
  2. (**************************************)
  3. (* Conversión Número -> Letra *)
  4. (* *)
  5. (* Parámetros: *)
  6. (* *)
  7. (* mNum: Número a convertir *)
  8. (* iIdioma: Idioma de conversión *)
  9. (* 1 -> Castellano *)
  10. (* 2 -> Catalán *)
  11. (* iModo: Modo de conversión *)
  12. (* 1 -> Masculino *)
  13. (* 2 -> Femenino *)
  14. (* *)
  15. (* Restricciones: *)
  16. (* *)
  17. (* - Redondeo a dos decimales *)
  18. (* - Rango: 0,00 a 999.999.999.999,99 *)
  19. (* *)
  20. (**************************************)
  21.  
  22. interface
  23.  
  24. function NumeroToLetra( mNum:double ): String;
  25.  
  26. implementation
  27.  
  28. uses
  29. sysUtils;
  30.  
  31. function NumeroToLetra( mNum:double ): String;
  32. const
  33. iIdioma : Smallint = 1; // 1 castellano 2 catalán
  34. iModo : Smallint = 1; // 1 masculino 2 femenino
  35.  
  36. iTopFil: Smallint = 6;
  37. iTopCol: Smallint = 10;
  38. aCastellano: array[0..5, 0..9] of PChar =
  39. ( ('UNA ','DOS ','TRES ','CUATRO ','CINCO ',
  40. 'SEIS ','SIETE ','OCHO ','NUEVE ','UN '),
  41. ('ONCE ','DOCE ','TRECE ','CATORCE ','QUINCE ',
  42. 'DIECISEIS ','DIECISIETE ','DIECIOCHO ','DIECINUEVE ',''),
  43. ('DIEZ ','VEINTE ','TREINTA ','CUARENTA ','CINCUENTA ',
  44. 'SESENTA ','SETENTA ','OCHENTA ','NOVENTA ','VEINTI'),
  45. ('CIEN ','DOSCIENTAS ','TRESCIENTAS ','CUATROCIENTAS ','QUINIENTAS ',
  46. 'SEISCIENTAS ','SETECIENTAS ','OCHOCIENTAS ','NOVECIENTAS ','CIENTO '),
  47. ('CIEN ','DOSCIENTOS ','TRESCIENTOS ','CUATROCIENTOS ','QUINIENTOS ',
  48. 'SEISCIENTOS ','SETECIENTOS ','OCHOCIENTOS ','NOVECIENTOS ','CIENTO '),
  49. ('MIL ','MILLON ','MILLONES ','CERO ','Y ',
  50. 'UNO ','DOS ','CON ','','') );
  51. aCatalan: array[0..5, 0..9] of PChar =
  52. ( ( 'UNA ','DUES ','TRES ','QUATRE ','CINC ',
  53. 'SIS ','SET ','VUIT ','NOU ','UN '),
  54. ( 'ONZE ','DOTZE ','TRETZE ','CATORZE ','QUINZE ',
  55. 'SETZE ','DISSET ','DIVUIT ','DINOU ',''),
  56. ( 'DEU ','VINT ','TRENTA ','QUARANTA ','CINQUANTA ',
  57. 'SEIXANTA ','SETANTA ','VUITANTA ','NORANTA ','VINT-I-'),
  58. ( 'CENT ','DOS-CENTES ','TRES-CENTES ','QUATRE-CENTES ','CINC-CENTES ',
  59. 'SIS-CENTES ','SET-CENTES ','VUIT-CENTES ','NOU-CENTES ','CENT '),
  60. ( 'CENT ','DOS-CENTS ','TRES-CENTS ','QUATRE-CENTS ','CINC-CENTS ',
  61. 'SIS-CENTS ','SET-CENTS ','VUIT-CENTS ','NOU-CENTS ','CENT '),
  62. ( 'MIL ','MILIO ','MILIONS ','ZERO ','-',
  63. 'UN ','DOS ','AMB ','','') );
  64. var
  65. aTexto: array[0..5, 0..9] of PChar;
  66. cTexto, cNumero: String;
  67. iCentimos, iPos: Smallint;
  68. bHayCentimos, bHaySigni, negativo: Boolean;
  69.  
  70. (*************************************)
  71. (* Cargar Textos según Idioma / Modo *)
  72. (*************************************)
  73.  
  74. procedure NumLetra_CarTxt;
  75. var
  76. i, j: Smallint;
  77. begin
  78. (* Asignación según Idioma *)
  79.  
  80. for i := 0 to iTopFil - 1 do
  81. for j := 0 to iTopCol - 1 do
  82. case iIdioma of
  83. 1: aTexto[i, j] := aCastellano[i, j];
  84. 2: aTexto[i, j] := aCatalan[i, j];
  85. else
  86. aTexto[i, j] := aCastellano[i, j];
  87. end;
  88.  
  89. (* Asignación si Modo Masculino *)
  90.  
  91. if (iModo = 1) then
  92. begin
  93. for j := 0 to 1 do
  94. aTexto[0, j] := aTexto[5, j + 5];
  95.  
  96. for j := 0 to 9 do
  97. aTexto[3, j] := aTexto[4, j];
  98. end;
  99. end;
  100.  
  101. (****************************)
  102. (* Traducir Dígito -Unidad- *)
  103. (****************************)
  104.  
  105. procedure NumLetra_Unidad;
  106. begin
  107. if not( (cNumero[iPos] = '0') or (cNumero[iPos - 1] = '1')
  108. or ((Copy(cNumero, iPos - 2, 3) = '001') and ((iPos = 3) or (iPos = 9))) ) then
  109. if (cNumero[iPos] = '1') and (iPos <= 6) then
  110. cTexto := cTexto + aTexto[0, 9]
  111. else
  112. cTexto := cTexto + aTexto[0, StrToInt(cNumero[iPos]) - 1];
  113.  
  114. if ((iPos = 3) or (iPos = 9)) and (Copy(cNumero, iPos - 2, 3) <> '000') then
  115. cTexto := cTexto + aTexto[5, 0];
  116.  
  117. if (iPos = 6) then
  118. if (Copy(cNumero, 1, 6) = '000001') then
  119. cTexto := cTexto + aTexto[5, 1]
  120. else
  121. cTexto := cTexto + aTexto[5, 2];
  122. end;
  123.  
  124. (****************************)
  125. (* Traducir Dígito -Decena- *)
  126. (****************************)
  127.  
  128. procedure NumLetra_Decena;
  129. begin
  130. if (cNumero[iPos] = '0') then
  131. Exit
  132. else if (cNumero[iPos + 1] = '0') then
  133. cTexto := cTexto + aTexto[2, StrToInt(cNumero[iPos]) - 1]
  134. else if (cNumero[iPos] = '1') then
  135. cTexto := cTexto + aTexto[1, StrToInt(cNumero[iPos + 1]) - 1]
  136. else if (cNumero[iPos] = '2') then
  137. cTexto := cTexto + aTexto[2, 9]
  138. else
  139. cTexto := cTexto + aTexto[2, StrToInt(cNumero[iPos]) - 1]
  140. + aTexto[5, 4];
  141. end;
  142.  
  143. (*****************************)
  144. (* Traducir Dígito -Centena- *)
  145. (*****************************)
  146.  
  147. procedure NumLetra_Centena;
  148. var
  149. iPos2: Smallint;
  150. begin
  151. if (cNumero[iPos] = '0') then
  152. Exit;
  153.  
  154. iPos2 := 4 - Ord(iPos > 6);
  155.  
  156. if (cNumero[iPos] = '1') and (Copy(cNumero, iPos + 1, 2) <> '00') then
  157. cTexto := cTexto + aTexto[iPos2, 9]
  158. else
  159. cTexto := cTexto + aTexto[iPos2, StrToInt(cNumero[iPos]) - 1];
  160. end;
  161.  
  162. (**************************************)
  163. (* Eliminar Blancos previos a guiones *)
  164. (**************************************)
  165.  
  166. procedure NumLetra_BorBla;
  167. var
  168. i: Smallint;
  169. begin
  170. i := Pos(' -', cTexto);
  171.  
  172. while (i > 0) do
  173. begin
  174. Delete(cTexto, i, 1);
  175. i := Pos(' -', cTexto);
  176. end;
  177. end;
  178.  
  179. begin
  180. (* Control de Argumentos *)
  181.  
  182. if {(mNum < 0.00) or }(mNum > 999999999999.99) or (iIdioma < 1) or (iIdioma > 2)
  183. or (iModo < 1) or (iModo > 2) then
  184. begin
  185. Result := 'ERROR EN ARGUMENTOS';
  186. Abort;
  187. end;
  188.  
  189. // Por si es negativo...
  190. if mNum < 0.00 then begin
  191. negativo:=TRUE;
  192. mNum:=ABS(mNum);
  193. end
  194. else
  195. negativo:=FALSE;
  196.  
  197. (* Cargar Textos según Idioma / Modo *)
  198.  
  199. NumLetra_CarTxt;
  200.  
  201. (* Bucle Exterior -Tratamiento Céntimos- *)
  202. (* NOTA: Se redondea a dos dígitos decimales *)
  203.  
  204. cNumero := Trim(Format('%12.0f', [Int(mNum)]));
  205. cNumero := StringOfChar('0', 12 - Length(cNumero)) + cNumero;
  206. iCentimos := Trunc((Frac(mNum) * 100) + 0.5);
  207.  
  208. repeat
  209. (* Detectar existencia de Céntimos *)
  210.  
  211. if (iCentimos <> 0) then
  212. bHayCentimos := True
  213. else
  214. bHayCentimos := False;
  215.  
  216. (* Bucle Interior -Traducción- *)
  217.  
  218. bHaySigni := False;
  219.  
  220. for iPos := 1 to 12 do
  221. begin
  222. (* Control existencia Dígito significativo *)
  223.  
  224. if not(bHaySigni) and (cNumero[iPos] = '0') then
  225. Continue
  226. else
  227. bHaySigni := True;
  228.  
  229. (* Detectar Tipo de Dígito *)
  230.  
  231. case ((iPos - 1) mod 3) of
  232. 0: NumLetra_Centena;
  233. 1: NumLetra_Decena;
  234. 2: NumLetra_Unidad;
  235. end;
  236. end;
  237.  
  238. (* Detectar caso 0 *)
  239.  
  240. if (cTexto = '') then
  241. cTexto := aTexto[5, 3];
  242.  
  243. (* Traducir Céntimos -si procede- *)
  244.  
  245. if (iCentimos <> 0) then
  246. begin
  247. cTexto := cTexto + aTexto[5, 7];
  248. cNumero := Trim(Format('%.12d', [iCentimos]));
  249. iCentimos := 0;
  250. end;
  251. until not (bHayCentimos);
  252.  
  253. (* Eliminar Blancos innecesarios -sólo Catalán- *)
  254.  
  255. if (iIdioma = 2) then
  256. NumLetra_BorBla;
  257.  
  258. (* ...Por si es negativo *)
  259. if negativo then
  260. cTexto:='MENOS '+cTexto;
  261.  
  262. (* Retornar Resultado *)
  263.  
  264. Result := Trim(cTexto);
  265. end;
  266.  
  267. end.

Espero te sirva. Nunca me ha fallado.


  • 0

#5 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.248 mensajes
  • LocationArgentina

Escrito 29 mayo 2019 - 05:56

La diferencia entre el "UNO" y el "UN" se debe al contexto en el que se lo usa. Cuando el número tiene un patrón de medida, y en situaciones monetarias, se utiliza "un" mientras que si es adimensional (no tiene patrón) corresponde el "uno". Por ejemplo:

 

$41 = cuarenta y un pesos

81kg = ochenta y un kilogramos (o kilos, se usan ambas indistintamente)

31% = treinta y un por cierto. También en lugar de "por cierto", en algunos lugares se estila decir "por cien"

 

171 = ciento setenta y uno (no hay patrón de medida es simplemente un número)

 

Téngase especial cuidado cuando se trata de expresiones monetarias por que en cada lugar se establece por ley como han de mencionarse los centavos en letras. Menciono algunos estilos que conozco:

$145,96 = son pesos ciento cuarenta y cinco, con noventa y seis centavos

$63,32 = son pesos sesenta y tres, y treinta y dos centavos

$314,21 = trescientos catorce pesos con/y veinti y un centavos

 

Asi que antes de ponerse a usar funciones traídas de cualquier lado, primero se aseguren de que si van a darle uso contable/monetario, que respeta la ley comercial de su país.

 

Saludos,


  • 0

#6 santiago14

santiago14

    Advanced Member

  • Miembros
  • PipPipPip
  • 322 mensajes
  • LocationCerrillos - Salta - Argentina

Escrito 29 mayo 2019 - 05:06

Bueno, en mi caso le hice unas pequeñas codificaciones para Argentina.
No se ve en este, pero le agregué “centavos” al final.
Ejemplo: 132,34
Sería: ciento treinta y dos con treinta y dos centavos.
Toda mi facturación electrónica lleva ese texto y no he tenido problemas hasta hoy.


Enviado desde mi iPhone utilizando Tapatalk
  • 0

#7 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.248 mensajes
  • LocationArgentina

Escrito 29 mayo 2019 - 07:51

Bueno, en mi caso le hice unas pequeñas codificaciones para Argentina.
No se ve en este, pero le agregué “centavos” al final.
Ejemplo: 132,34
Sería: ciento treinta y dos con treinta y dos centavos.
Toda mi facturación electrónica lleva ese texto y no he tenido problemas hasta hoy.


Enviado desde mi iPhone utilizando Tapatalk

 

Ojo. Porque los 3 casos que he citado corresponden a los que usamos en Argentina. Yo he visto en varios lados a las 3 formas, y ya me marea en saber cuando o en que tipo de documento se emplea cada una.

Durante un tiempo en los pagarés no se ponía con letras los centavos, se ponía algo así: "son pesos novecientos catorce y 15/100". Y en otros tiempos se permitía abreviar centavos por ctvos. Es cierto que quizá la más empleada es la 1ra forma (la que usa el "con") pero no es la única. Lamentablemente no tengo a mano, ni recuerdo, en que código/ley/norma estaba regulado este tema.

 

Ya tengo oxidado lo que aprendí en contabilidad :(

 

Saludos,


  • 0

#8 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 13.948 mensajes
  • LocationMéxico

Escrito 30 mayo 2019 - 07:33

Ojo. Porque los 3 casos que he citado corresponden a los que usamos en Argentina. Yo he visto en varios lados a las 3 formas, y ya me marea en saber cuando o en que tipo de documento se emplea cada una.

Durante un tiempo en los pagarés no se ponía con letras los centavos, se ponía algo así: "son pesos novecientos catorce y 15/100". Y en otros tiempos se permitía abreviar centavos por ctvos. Es cierto que quizá la más empleada es la 1ra forma (la que usa el "con") pero no es la única. Lamentablemente no tengo a mano, ni recuerdo, en que código/ley/norma estaba regulado este tema.

 

Ya tengo oxidado lo que aprendí en contabilidad :(

 

Saludos,

 

 

Acá en México los centavos se muestran como lo mencionas amigo Marchello,

 

Así por ejemplo, $123.45 se convierte a letra de ésta forma:    Ciento veintitres pesos 45/100 M.N.

 

M.N. = Moneda Nacional

 

Saludos


  • 0