Google Apps Script uses JavaScript under the hood, which means you can leverage charCodeAt() and String.fromCharCode() to convert letters to numbers directly inside Google Sheets. This tutorial covers custom functions, batch processing, and automated triggers for letter-to-number conversion. For a quick conversion without scripting, try our letters to numbers converter.
Your First Custom Function
Open your Google Sheet, go to Extensions > Apps Script, and paste this code. Once saved, you can call it from any cell.
/**
* Converts a letter to its alphabet position (A=1, Z=26).
* @param {string} letter - A single letter.
* @return {number} The position (1-26) or -1 if not a letter.
* @customfunction
*/
function LETTERTONUM(letter) {
if (typeof letter !== "string" || letter.length === 0) return -1;
var c = letter.charAt(0).toUpperCase();
var code = c.charCodeAt(0);
if (code >= 65 && code <= 90) {
return code - 64;
}
return -1;
}
// Usage in Sheets:
// =LETTERTONUM("A") → 1
// =LETTERTONUM("m") → 13
// =LETTERTONUM("Z") → 26Encode an Entire String
/**
* Encodes text as A1Z26 number sequence.
* @param {string} text - The text to encode.
* @param {string} [sep="-"] - Separator between numbers.
* @return {string} Encoded number sequence.
* @customfunction
*/
function ENCODEA1Z26(text, sep) {
if (!sep) sep = "-";
if (typeof text !== "string") text = String(text);
var result = [];
var upper = text.toUpperCase();
for (var i = 0; i < upper.length; i++) {
var code = upper.charCodeAt(i);
if (code >= 65 && code <= 90) {
result.push(code - 64);
}
}
return result.join(sep);
}
// =ENCODEA1Z26("Hello") → "8-5-12-12-15"
// =ENCODEA1Z26("Hello", ",") → "8,5,12,12,15"
// =ENCODEA1Z26("Apps Script") → "1-16-16-19-19-3-18-9-16-20"Decode Numbers Back to Text
/**
* Decodes A1Z26 numbers back to letters.
* @param {string} encoded - Dash-separated numbers like "8-5-12-12-15".
* @param {string} [sep="-"] - Separator used in encoding.
* @return {string} Decoded text.
* @customfunction
*/
function DECODEA1Z26(encoded, sep) {
if (!sep) sep = "-";
if (typeof encoded !== "string") encoded = String(encoded);
var parts = encoded.split(sep);
var result = "";
for (var i = 0; i < parts.length; i++) {
var num = parseInt(parts[i].trim(), 10);
if (num >= 1 && num <= 26) {
result += String.fromCharCode(num + 64);
}
}
return result;
}
// =DECODEA1Z26("8-5-12-12-15") → "HELLO"
// =DECODEA1Z26("1,16,16,19", ",") → "APPS"Word Value Calculator
/**
* Calculates the word value (sum of letter positions).
* @param {string} text - The text to calculate.
* @return {number} Sum of all letter positions.
* @customfunction
*/
function WORDVALUE(text) {
if (typeof text !== "string") text = String(text);
var sum = 0;
var upper = text.toUpperCase();
for (var i = 0; i < upper.length; i++) {
var code = upper.charCodeAt(i);
if (code >= 65 && code <= 90) {
sum += code - 64;
}
}
return sum;
}
// =WORDVALUE("HELLO") → 52
// =WORDVALUE("Google") → 57 (7+15+15+7+12+5 → wait: G=7+O=15+O=15+G=7+L=12+E=5 = 61)You can verify word values using our Google Sheets formulas guide or the browser-based column converter.
Batch Processing: Convert an Entire Column
Custom functions run one cell at a time, which can be slow for large datasets. For batch processing, use a regular function with getRange() and setValues():
function batchEncodeColumn() {
var sheet = SpreadsheetApp.getActiveSheet();
var sourceRange = sheet.getRange("A2:A" + sheet.getLastRow());
var values = sourceRange.getValues();
var output = values.map(function(row) {
var text = String(row[0]);
if (text.trim() === "") return [""];
var upper = text.toUpperCase();
var nums = [];
for (var i = 0; i < upper.length; i++) {
var code = upper.charCodeAt(i);
if (code >= 65 && code <= 90) {
nums.push(code - 64);
}
}
return [nums.join("-")];
});
// Write results to column B
var outputRange = sheet.getRange(2, 2, output.length, 1);
outputRange.setValues(output);
SpreadsheetApp.getUi().alert(
"Converted " + output.length + " rows!"
);
}
// Add a menu item to run this easily
function onOpen() {
SpreadsheetApp.getUi()
.createMenu("A1Z26 Tools")
.addItem("Encode Column A → B", "batchEncodeColumn")
.addItem("Create Reference Table", "createReferenceTable")
.addToUi();
}Automatic Conversion with onEdit Trigger
The onEdit() trigger fires every time a cell is edited. Use it to automatically convert letters as users type:
function onEdit(e) {
var sheet = e.source.getActiveSheet();
var range = e.range;
// Only trigger for column A (column 1)
if (range.getColumn() !== 1) return;
// Only trigger on the "Data" sheet
if (sheet.getName() !== "Data") return;
var text = String(range.getValue());
if (text.trim() === "") {
range.offset(0, 1).setValue("");
return;
}
// Encode and write to column B (same row)
var upper = text.toUpperCase();
var nums = [];
for (var i = 0; i < upper.length; i++) {
var code = upper.charCodeAt(i);
if (code >= 65 && code <= 90) {
nums.push(code - 64);
}
}
range.offset(0, 1).setValue(nums.join("-"));
range.offset(0, 2).setValue(nums.reduce(function(a, b) {
return a + b;
}, 0));
}
// When user types "Hello" in A2:
// B2 automatically shows "8-5-12-12-15"
// C2 automatically shows 52Installable Triggers for Scheduled Conversions
// Set up a time-based trigger to process a queue
function createDailyTrigger() {
ScriptApp.newTrigger("processConversionQueue")
.timeBased()
.everyDays(1)
.atHour(9)
.create();
}
function processConversionQueue() {
var sheet = SpreadsheetApp.openById("YOUR_SHEET_ID")
.getSheetByName("Queue");
var data = sheet.getDataRange().getValues();
var processed = 0;
for (var i = 1; i < data.length; i++) {
if (data[i][0] && !data[i][1]) {
// Column A has text, column B is empty
var text = String(data[i][0]);
var encoded = ENCODEA1Z26(text);
var value = WORDVALUE(text);
sheet.getRange(i + 1, 2).setValue(encoded);
sheet.getRange(i + 1, 3).setValue(value);
sheet.getRange(i + 1, 4).setValue(new Date());
processed++;
}
}
Logger.log("Processed " + processed + " rows");
}Building a Complete Reference Table
function createReferenceTable() {
var sheet = SpreadsheetApp.getActiveSpreadsheet()
.insertSheet("A-Z Reference");
// Headers
var headers = [
"Letter", "Position", "ASCII (Upper)", "ASCII (Lower)",
"Hex", "Binary"
];
sheet.getRange(1, 1, 1, headers.length).setValues([headers]);
sheet.getRange(1, 1, 1, headers.length)
.setFontWeight("bold")
.setBackground("#f0f0f0");
// Data
var data = [];
for (var i = 0; i < 26; i++) {
var upper = String.fromCharCode(65 + i);
var asciiUpper = 65 + i;
var asciiLower = 97 + i;
data.push([
upper,
i + 1,
asciiUpper,
asciiLower,
"0x" + asciiUpper.toString(16).toUpperCase(),
asciiUpper.toString(2).padStart(8, "0")
]);
}
sheet.getRange(2, 1, data.length, data[0].length).setValues(data);
sheet.autoResizeColumns(1, headers.length);
}Skip the scripting: Our Excel Column Converter handles column letter-to-number conversions instantly in your browser.
Frequently Asked Questions
How do I create a custom letter-to-number function in Google Sheets?
Open Extensions > Apps Script and add a function with the @customfunction JSDoc tag. Use charCodeAt(0) - 64 to convert uppercase letters to positions 1-26. Once saved, type =LETTERTONUM("A") in any cell and it works like a built-in function.
Can I batch convert an entire column of text to numbers in Google Sheets?
Yes, use getRange().getValues() to read all cells at once, process them in a loop, then write results with setValues(). This is much faster than applying a custom function to each cell individually because it makes only two API calls regardless of row count.
How do I set up automatic letter conversion with Apps Script triggers?
Use the simple onEdit(e) trigger for real-time conversion as users type. Check e.range.getColumn() to limit which columns trigger conversion. For scheduled batch processing, use ScriptApp.newTrigger() to create a time-based trigger that runs your conversion function daily or hourly.