Skip to content

Instantly share code, notes, and snippets.

@alfchee
Last active July 11, 2024 23:02
Show Gist options
  • Save alfchee/e563340276f89b22042a to your computer and use it in GitHub Desktop.
Save alfchee/e563340276f89b22042a to your computer and use it in GitHub Desktop.
Código en JavaScript que convierte números a letras, bastante útil para formularios de documentos contables y similares
/*************************************************************/
// NumeroALetras
// The MIT License (MIT)
//
// Copyright (c) 2015 Luis Alfredo Chee
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
// @author Rodolfo Carmona
// @contributor Jean (jpbadoino@gmail.com)
/*************************************************************/
function Unidades(num){
switch(num)
{
case 1: return “UN”;
case 2: return “DOS”;
case 3: return “TRES”;
case 4: return “CUATRO”;
case 5: return “CINCO”;
case 6: return “SEIS”;
case 7: return “SIETE”;
case 8: return “OCHO”;
case 9: return “NUEVE”;
}
return “”;
}//Unidades()
function Decenas(num){
decena = Math.floor(num/10);
unidad = num – (decena * 10);
switch(decena)
{
case 1:
switch(unidad)
{
case 0: return “DIEZ”;
case 1: return “ONCE”;
case 2: return “DOCE”;
case 3: return “TRECE”;
case 4: return “CATORCE”;
case 5: return “QUINCE”;
default: return “DIECI” + Unidades(unidad);
}
case 2:
switch(unidad)
{
case 0: return “VEINTE”;
default: return “VEINTI” + Unidades(unidad);
}
case 3: return DecenasY(“TREINTA”, unidad);
case 4: return DecenasY(“CUARENTA”, unidad);
case 5: return DecenasY(“CINCUENTA”, unidad);
case 6: return DecenasY(“SESENTA”, unidad);
case 7: return DecenasY(“SETENTA”, unidad);
case 8: return DecenasY(“OCHENTA”, unidad);
case 9: return DecenasY(“NOVENTA”, unidad);
case 0: return Unidades(unidad);
}
}//Unidades()
function DecenasY(strSin, numUnidades) {
if (numUnidades > 0)
return strSin + ” Y ” + Unidades(numUnidades)
return strSin;
}//DecenasY()
function Centenas(num) {
centenas = Math.floor(num / 100);
decenas = num – (centenas * 100);
switch(centenas)
{
case 1:
if (decenas > 0)
return “CIENTO ” + Decenas(decenas);
return “CIEN”;
case 2: return “DOSCIENTOS ” + Decenas(decenas);
case 3: return “TRESCIENTOS ” + Decenas(decenas);
case 4: return “CUATROCIENTOS ” + Decenas(decenas);
case 5: return “QUINIENTOS ” + Decenas(decenas);
case 6: return “SEISCIENTOS ” + Decenas(decenas);
case 7: return “SETECIENTOS ” + Decenas(decenas);
case 8: return “OCHOCIENTOS ” + Decenas(decenas);
case 9: return “NOVECIENTOS ” + Decenas(decenas);
}
return Decenas(decenas);
}//Centenas()
function Seccion(num, divisor, strSingular, strPlural) {
cientos = Math.floor(num / divisor)
resto = num – (cientos * divisor)
letras = “”;
if (cientos > 0)
if (cientos > 1)
letras = Centenas(cientos) + ” ” + strPlural;
else
letras = strSingular;
if (resto > 0)
letras += “”;
return letras;
}//Seccion()
function Miles(num) {
divisor = 1000;
cientos = Math.floor(num / divisor)
resto = num – (cientos * divisor)
strMiles = Seccion(num, divisor, “UN MIL”, “MIL”);
strCentenas = Centenas(resto);
if(strMiles == “”)
return strCentenas;
return strMiles + ” ” + strCentenas;
}//Miles()
function Millones(num) {
divisor = 1000000;
cientos = Math.floor(num / divisor)
resto = num – (cientos * divisor)
strMillones = Seccion(num, divisor, “UN MILLON DE”, “MILLONES DE”);
strMiles = Miles(resto);
if(strMillones == “”)
return strMiles;
return strMillones + ” ” + strMiles;
}//Millones()
function NumeroALetras(num) {
var data = {
numero: num,
enteros: Math.floor(num),
centavos: (((Math.round(num * 100)) – (Math.floor(num) * 100))),
letrasCentavos: “”,
letrasMonedaPlural: 'Córdobas',//“PESOS”, 'Dólares', 'Bolívares', 'etcs'
letrasMonedaSingular: 'Córdoba', //“PESO”, 'Dólar', 'Bolivar', 'etc'
letrasMonedaCentavoPlural: “CENTAVOS”,
letrasMonedaCentavoSingular: “CENTAVO”
};
if (data.centavos > 0) {
data.letrasCentavos = “CON ” + (function (){
if (data.centavos == 1)
return Millones(data.centavos) + ” ” + data.letrasMonedaCentavoSingular;
else
return Millones(data.centavos) + ” ” + data.letrasMonedaCentavoPlural;
})();
};
if(data.enteros == 0)
return “CERO ” + data.letrasMonedaPlural + ” ” + data.letrasCentavos;
if (data.enteros == 1)
return Millones(data.enteros) + ” ” + data.letrasMonedaSingular + ” ” + data.letrasCentavos;
else
return Millones(data.enteros) + ” ” + data.letrasMonedaPlural + ” ” + data.letrasCentavos;
}//NumeroALetras()
@Krohm64
Copy link

Krohm64 commented Jun 15, 2024

Señores.

El definitivo que funciona en las hojas de cálculo en Google Drive, metiendo el código en App Scripts.

  • Este código no tiene en cuenta ninguna divisa o moneda, de ningún país. Es decir, vale para convertir a letra cualquier cifra. Poned luego vuestra moneda si lo necesitáis con Concatenar, por ejemplo.
  • Se han depurado los espacios sobrantes entre palabras que venían mal en alguna de las propuestas anteriores.
  • Usa correctamente el castellano para acentuar palabras como veintitrés, dieciséis, veintiún, etc.
  • En los millares, cuando estos son uno (51.000), dirá «cincuenta y un mil», y no «cincuenta y uno mil». También funciona con [veintiún mil].

La función en la hoja de cálculo será igual:
numeroaletras(A1)

Espero que os valga.

function Unidades(num) {
    switch(num) {
        case 1: return 'uno';
        case 2: return 'dos';
        case 3: return 'tres';
        case 4: return 'cuatro';
        case 5: return 'cinco';
        case 6: return 'seis';
        case 7: return 'siete';
        case 8: return 'ocho';
        case 9: return 'nueve';
    }
    return '';
}

function Decenas(num) {
    let decena = Math.floor(num / 10);
    let unidad = num - (decena * 10);
    switch(decena) {
        case 1:
            switch(unidad) {
                case 0: return 'diez';
                case 1: return 'once';
                case 2: return 'doce';
                case 3: return 'trece';
                case 4: return 'catorce';
                case 5: return 'quince';
                default: return 'dieci' + Unidades(unidad);
            }
        case 2:
            if(unidad == 0)
                return 'veinte';
            else
                return 'veinti' + Unidades(unidad);
        case 3: return DecenasY('treinta', unidad);
        case 4: return DecenasY('cuarenta', unidad);
        case 5: return DecenasY('cincuenta', unidad);
        case 6: return DecenasY('sesenta', unidad);
        case 7: return DecenasY('setenta', unidad);
        case 8: return DecenasY('ochenta', unidad);
        case 9: return DecenasY('noventa', unidad);
        case 0: return Unidades(unidad);
    }
}

function DecenasY(strSin, numUnidades) {
    if (numUnidades > 0)
        return strSin + ' y ' + Unidades(numUnidades);
    return strSin;
}

function Centenas(num) {
    let centenas = Math.floor(num / 100);
    let decenas = num - (centenas * 100);
    switch(centenas) {
        case 1:
            if (decenas > 0)
                return 'ciento ' + Decenas(decenas);
            return 'cien';
        case 2: return 'doscientos ' + Decenas(decenas);
        case 3: return 'trescientos ' + Decenas(decenas);
        case 4: return 'cuatrocientos ' + Decenas(decenas);
        case 5: return 'quinientos ' + Decenas(decenas);
        case 6: return 'seiscientos ' + Decenas(decenas);
        case 7: return 'setecientos ' + Decenas(decenas);
        case 8: return 'ochocientos ' + Decenas(decenas);
        case 9: return 'novecientos ' + Decenas(decenas);
    }
    return Decenas(decenas);
}

function Seccion(num, divisor, strSingular, strPlural) {
    let cientos = Math.floor(num / divisor);
    let resto = num - (cientos * divisor);
    let letras = '';
    if (cientos > 0)
        if (cientos > 1)
            letras = Centenas(cientos) + ' ' + strPlural;
        else
            letras = strSingular;
    if (resto > 0)
        letras += ' ';
    return letras.trim();  // Eliminamos espacios al final
}

function Miles(num) {
    let divisor = 1000;
    let cientos = Math.floor(num / divisor);
    let resto = num - (cientos * divisor);
    let strMiles = Seccion(num, divisor, 'mil', 'mil');
    let strCentenas = Centenas(resto);
    if (cientos === 1) {
        strMiles = 'mil';
    } else if (cientos === 21) {
        strMiles = 'veintiún mil';
    } else if (cientos > 1) {
        strMiles = Centenas(cientos).replace('uno', 'un') + ' mil';
    }
    if(strMiles === '')
        return strCentenas;
    return strMiles + ' ' + strCentenas;
}

function Millones(num) {
    let divisor = 1000000;
    let cientos = Math.floor(num / divisor);
    let resto = num - (cientos * divisor);
    let strMillones = Seccion(num, divisor, 'un millón', 'millones');
    let strMiles = Miles(resto);
    if(strMillones === '')
        return strMiles;
    return strMillones + ' ' + strMiles;
}

function NumeroALetras(num, currency) {
    currency = currency || {};
    let data = {
        numero: num,
        enteros: Math.floor(num),
        centavos: (((Math.round(num * 100)) - (Math.floor(num) * 100))),
        letrasCentavos: '',
        letrasMonedaPlural: currency.plural || '',
        letrasMonedaSingular: currency.singular || '',
        letrasMonedaCentavoPlural: currency.centPlural || '',
        letrasMonedaCentavoSingular: currency.centSingular || ''
    };

    if (data.centavos > 0) {
        data.letrasCentavos = 'con ' + NumeroALetras(data.centavos).trim() + ' ' + (data.centavos === 1 ? data.letrasMonedaCentavoSingular : data.letrasMonedaCentavoPlural);
    }

    let letrasEnteros = Millones(data.enteros).trim();
    letrasEnteros = letrasEnteros.replace('dieciseis', 'dieciséis');
    letrasEnteros = letrasEnteros.replace('veintidos', 'veintidós');
    letrasEnteros = letrasEnteros.replace('veintitres', 'veintitrés');
    letrasEnteros = letrasEnteros.replace('veintiseis', 'veintiséis');
    
    if(data.enteros === 0)
        return 'cero ' + data.letrasMonedaPlural + ' ' + data.letrasCentavos.trim();
    if (data.enteros === 1)
        return letrasEnteros + ' ' + data.letrasMonedaSingular + ' ' + data.letrasCentavos.trim();
    else
        return letrasEnteros + ' ' + data.letrasMonedaPlural + ' ' + data.letrasCentavos.trim();
}

function convertirNumeroALetras(num) {
    if (num === undefined || isNaN(num)) {
        return '';
    }
    let partes = num.toString().split('.');
    let enteros = parseInt(partes[0], 10);
    let decimales = partes.length > 1 ? parseInt(partes[1].slice(0, 2), 10) : 0;

    let letrasEnteros = NumeroALetras(enteros).trim();  // Usamos .trim() para eliminar espacios extra
    let letrasDecimales = decimales > 0 ? `con ${NumeroALetras(decimales).trim()}` : '';

    return `${letrasEnteros} ${letrasDecimales}`.trim();
}

// Función que se usará en la hoja de cálculo de Google
function numeroALetras(celda) {
    return convertirNumeroALetras(celda);
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment