Google Scripts Returning Not a Number - javascript

I've been working on Google Scripts for a bit, but I can't seem to find the solution to my problem. What I am trying to do is multiply the contents of two cells on a spreadsheet together with my function calculateRates(). Here is my code:
/**
#customFunction
*/
function calculateRates(hourDecimal, personRate) {
var ss = SpreadsheetApp.getActiveSpreadsheet(); //Access spreadsheet
var sheet = ss.getSheets()[0]; //Access sheet
var range = sheet.getDataRange(); //Access all cells
var values = range.getValues(); //Call to get value of certain cell
var totalEarned = hourDecimal * personRate;
Logger.log(totalEarned);
return totalEarned;
}
The problem with it is that after I designate two cells to multiply together as the parameters of the function on the spreadsheet, there is an error that reads "Result was not a number." I know I have the function correct on my spreadsheet, so that can't be the problem..... Any ideas? Thanks for your help!

This error occurs when you try to perform calculations with values that are not all numbers, example a Number and a String.
Google Sheets stores data depending on the value of the cell, the values may be of type Number, Boolean, Date, or String (Empty cells will return an empty String). When these values are used by Custom Functions, Apps Script treats them as the appropriate data type in JavaScript.
You need to make sure the values of the cells are Numbers, take into account that if the cell contains some space or other non-numeric characters like "2 2" or "3/2" it will be treated as String and you will need to trim or extract those special characters before any calculation.

Related

Match Function to Apps Script for Finding Closest but Less Than Date

I have an array of dates. I have a specific date "Search Date". I want to find the date in the array that is closest to but less than the Search Date and return the index of that date in the array.
Example: Suppose the array of dates is [8/1/21, 8/5/22, 8/5/23], indexed 1,2,3 for sake of example. Suppose my Search date is 9/17/22. The function should find the date 8/5/22 and return the index 2.
In Google Sheets, this is simply the match function:
How do I do this (and most efficiently) in Apps Script? The IndexOf() function seems to return only an exact match, which does not work in this case.
Thank you!
Explanation:
The idea would be to compare each date in the array with the search date and select the absolute minimum difference which will be the closest date to the search date:
const checkDif = checkDates.map(d=>searchDate - d).filter(v=>v>0);
const minIndex = checkDif.indexOf(Math.min(...checkDif))+1;
map is used to calculate the difference between the dates for every date in the input array.
filter is used to select only the positive differences (namely the dates that are smaller than the search date).
Math.min is used to calculate the minimum value of the array of the positive differences, therefore the closest date that is less than the search date.
indexOf is used to calculate the index of that minimum value.
We do +1 because array indexes in JavaScript start from 0 but it seems you want them to start from 1.
Solution:
See comments for further explanation and in case you want to change the ranges or the name of the sheet.
function closestDate() {
const ss = SpreadsheetApp.getActive();
const sh = ss.getSheetByName("Sheet1"); // name of the sheet
const searchDate = sh.getRange("B4").getValue(); // search date
const checkDates = sh.getRange("B1:D1").getValues().flat(); // input range
const checkDif = checkDates.map(d=>searchDate - d).filter(v=>v>0);
const minIndex = checkDif.indexOf(Math.min(...checkDif))+1;
console.log(minIndex); // 2
sh.getRange("B5").setValue(minIndex); // return the result to B5
}
Example that works with the code snippet:

Google Scripts / Sheets Add prefix to data once it has been entered into the cell

Objectives
Add a Prefix of CSC1[Leading Zeros] to a number such as 1291 or 12922 or 129223 this should apply to the whole column (Column F)
Ensure total string length is = 15 using padding of zeros so the cell value would be CSC100000001291
The user would only enter 1291 but I plan to make the script overwrite this to make the the cell value CSC100000001291
Can be done using a formula but across two columns but would prefer to use one column as it look tidier.
e.g [User Input] = [Final Cell Value]
- 1291 = CSC100000001291
- 12922 = CSC100000012922
Currently trying to work this one out
Use the following:
An onEdit trigger to check when someone has updated a cell
padStart() to add the leading zeros
replace() the first 4 zeros with "CSC1" (since only the first occurrence will be replaced if passing a string instead of regular expression)
setValue() to update the edited cell
function onEdit(e) {
if (e.range.columnStart == 1) { // Column A
const padded = e.value.padStart(15, 0);
e.range.setValue(padded.replace('0000', 'CSC1'));
}
}

How use a NumberFormat function on google apps script

I have a webapp that I get a value. I make an append row with this data for my sheet. However, I want that this data have a text format, because I want to get the value like I typed.
Some problems happen with my sheet, like an "and" be recognized as a number.
Ex: 2000e7 appears as: 2.00E + 10.
I know that yhave a function to change the format. NumberFormat (" ")
But I think that I'm not using it correctly.
My code:
var ws= ss.getSheetByName(flag);
ws.appendRow([Entrada,Modelo,SN,Ocorrencia,Status,data,obs])
var ss2 = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss2.getSheets()[0];
var range = sheet.getRange("My Last row");
// Money format
range.setNumberFormat("#");
Sometimes the better way is to prepend the value with ' rather than using setNumberFormat
Related
Script 'setValues' method interprets strings as numbers in cells

TextFinder StartFrom() not working correctly

I've been trying to tackle a small line of code for some time now, with no luck.
I have a text finder, which I need to start from the 3rd column (C)
var textFinder = responses.createTextFinder(tdate); var search_row = textFinder.startFrom(3).findNext().getRow();
I've also tried
textFinder.startFrom('C').findNext().getRow()
and
textFinder.startFrom(1,3,responses.getLastRow()).findNext().getRow()
Any help would be greatly appreciated, all I need is to get the row number of tdate - searched in column 3
startFrom(range) accepts range as the only argument. You can get a range from sheet or spreadsheet
textFinder.startFrom(responses.getRange('C1')).findNext().getRow()
Note that search starts from "C1" , but not restricted to column C.
Related Answer

Excel to XML: Round decimals to the nearest hundredth and keep hyperlinks

I followed this guide to export an Excel Spreadsheet as an XML data file and then this guide to display the XML sheet as an HTML table on my website. It worked great. Now I "only" have to small issues remaining that I couldn't get solved.
(1) The output table contains numbers like 1.325667 but also lots of 0s. I would like the zeroes to be displayed as 0.00 and the numbers with many decimals to be displayed as 1.33. Basically, each number should be displayed with two decimals.
(2) The excel sheet contains hyperlinks to other pages on my website that I would like to keep when rendering the XML data file and then the HTML table. So far, that didn't work. Is this possible?
UPDATE I figured this part out. By breaking up the hyperlinks in just their character-strings, then adding new columns for these character strings, and then tweaking the source code to including
document.write("<tr><td><a href='");
document.write(x[i].getElementsByTagName("character-string")0].childNodes[0].nodeValue);
document.write(".php'>");
document.write(x[i].getElementsByTagName("name")[0].childNodes[0].nodeValue);
document.write("</a></td>");
I was able to include hyperlinks.
The Excel-Sheet is formatted with these two aspects already integrated, but the conversion to an XML file seems to be the problem.
Thank you so much for your help (again and again :-))
UPDATE I now also found a way to do the rounding in Excel, but I'm still stuck with integers and numbers with only one decimal. Basically, I now "only" need a way to show every number with two decimal points, applying to integers (e.g. 0 should 0.00) and numbers with one decimal (e.g. 1.5 should be 1.50). JohnnyReeves' answer seems to be on the right track but I couldn't get it to work. Any other ideas?
The Number Object has the method toFixed():
1.325667.toFixed(2) = 1.33.
Running inside the loop of the XML, select the URL and add it to the link:
document.write("< a href=" + x[i].getElementsByTagName(< your URL link>) + ">);
document.write("some text");
document.write("< /a>");
The Number.toFixed method will only work on floating point values (eg: 2.1), but not on integers (eg: 2, or 0). You will need to convert your number type to a string type so you can format it for display and get consistent results regardless of the input. A function like this should do the trick:
function formatNumber(value) {
var parts,
trailingDigits,
formattedRemainder;
// Coerce the supplied value to a String type.
value = String(value);
// Break the supplied number into two parts, before and after the dot
parts = value.split(".");
// If there was no dot, there will only be one "part" and we can just
// add the trailing zeros.
if (parts.length === 1) {
formattedRemainder = "00";
}
else {
trailingDigits = parts[1];
if (trailingDigits.length === 0) {
// A dot, but no digits. (eg: 2. -> 2.00)
formattedRemainder = "00";
}
else if (trailingDigits.length === 1) {
// Add an extra trailing zero (eg: 2.1 -> 2.10)
formattedRemainder = trailingDigits + "0";
}
else {
// Just take the last two trailing digits.
formattedRemainder = trailingDigits.substring(0, 2);
}
}
// Build the final formatted string for display.
return parts[0] + "." + formattedRemainder;
}

Categories

Resources