I have a uiApp that is creating table views from spreadsheet data, but I'm having difficulty with empty cells in a date column.
Basically, some of the spreadsheet cells are optional, and I haven't figured out how to put no (or a null) value into the table. Right now it works if I set the column value to:
projectDataRaw[i][projectDataKeys[j]]= new Date(); // inserting dummy data
But I want to leave those cells blank in the table view too, however, when I use:
projectDataRaw[i][projectDataKeys[j]]= null; //
Or some variation of that, it errors because the column type is set to DATE.
I could convert to strings, but I kind of wanted to be able to compare date values to each other when they are available.
-- Example of issue with table view and null data --
// load data from sheet
var _PMsheet = "sheet key";
var sSheet = SpreadsheetApp.openById(_PMsheet);
var projectData = sSheet.getRangeByName("ProjectDateCol").getValues();
var projectDataTable = Charts.newDataTable();
projectDataTable.addColumn(Charts.ColumnType.DATE, "Date Column");
for (var i=0; i < projectData.length; i++) {
if (projectData[i] == undefined || projectData[i] == "undefined") {
projectDataTable.addRow([null]);// Object type does not match column type.
// null fails, "undefined" fails, "" fails, [] fails
}
else {
projectDataTable.addRow([projectData[i]]); // this cell has a valid date obj
}
}
I created a simple script which writes null to the A1 cell and current date to the A2 cell. The complete column A is validated to be a date time. After the script execution the cell A1 is empty even if it contained a value before and there is no any warning or error message.
function myFunction() {
var sheet = SpreadsheetApp.getActiveSheet();
var rangeValues = [[null], [new Date()]];
sheet.getRange("A1:A2").setValues(rangeValues);
}
If this example does not help you, please publish as smallest as possible working script which does not work as you expected.
Update, basing on the author clarification: I wrote a simple script trying to find the problem cause and to find a workaround. The code is bellow. If to uncomment the data.addRow(['', 2.0]); line, then an exception thrown by the addRow method. It is an expected behavior. If to uncomment the data.addRow([null, 3.0]); line, then the chart.setDataTable(data) line throws an exception. This behavior is not correct, from my point of view, and I think it is necessary to report an issue to the issue tracker.
Also there is a workaround of this problem by using the DataTableBuilder.setValue method. The code demonstrates it.
By the way, the DataTableBuilder.setValue description in the documentation is not correct. It does not contain the column parameter. It is a topic to the issue tracker.
function doGet(e) {
var app = UiApp.createApplication();
var chart = Charts.newTableChart();
var data = Charts.newDataTable();
data.addColumn(Charts.ColumnType.DATE, 'Date');
data.addColumn(Charts.ColumnType.NUMBER, 'Value');
data.addRow([new Date(), 1.0]);
// data.addRow(['', 2.0]); // throws the "Object type does not match column type" exception in this line.
// data.addRow([null, 3.0]); // throws the "We're sorry, a server error occurred. Please wait a bit and try again" exception in the "chart.setDataTable(data)" line.
data.setValue(1, 1, 3.0);
chart.setDataTable(data);
app.add(chart.build());
return app;
}
Related
I am getting the below error in GTM when I select preview:
enter image description here
I ran my script through JS Lint to make sure there were no errors, additionally I haven't changed anything to the line / character it is calling out so I'm not entirely sure what the fix is.
Here is a sample of what my script looks like:
function() {
// Set inputVariable to the input you want to assess
var inputVariable = {{Page URL}};
// Set defaultVal to what you want to return if no match is made
var defaultVal = undefined;
// Add rows as two-cell Arrays within the Array "table".
// The first cell contains the RegExp you want to match
// the inputVariable with, the second cell contains the
// return value if a match is made. The third cell (optional),
// contains any RegEx flags you want to use.
//
// The return value can be another GTM variable or any
// supported JavaScript type.
//
// Remember, no comma after the last row in the table Array,
// and remember to double escape reserved characters: \\?
// Row 1 is master, row 2 is staging. Repeat for every app
var table = [
//Website Name
["URL", "GA4 Lookup Reference Name"],
]; **<----- THIS IS THE LINE THAT IS GIVING ME ISSUES**
// Go through all the rows in the table, do the tests,
// and return the return value of the FIRST successful
// match.
for (var i = 0, len = table.length; i < len; i += 1) {
var regex = new RegExp(table[i][0], table[i][2]);
if (regex.test(inputVariable)) {
return table[i][1];
}
}
return defaultVal;
}
Any ideas what the fix is here?
I tried correcting the error by adding in an additional ','. I also looked at previous versions which worked and did not see any differences aside from some new URL's I've added in.
I'm trying to insert values into cells. Here is my code:
var values = [
["test1", "test2", "test3"]
];
var ss = SpreadsheetApp.getActiveSpreadsheet()
// var sheet = ss.getSheets()[0]
var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet()
var cellsToWriteTo = []
function testFunction() {
var activeCell = sheet.getActiveCell();
var firstRow = activeCell.getRow()
var firstColumn = activeCell.getColumn()
cellsToWriteTo = `["R${firstRow}C${firstColumn}:R${firstRow}C${firstColumn + 2}"]`
console.log(cellsToWriteTo)
var range = sheet.getRange(cellsToWriteTo)
range.setValues(values);
}
This gives me the error:
Exception: Range not found
However if I copy and paste cellsToWriteTo from the console log and put it into getRange.. it works perfectly every time..
Things i have tried so far:
Thought it was to do with not fetching the spreadsheet correctly (getActiveSpreadsheet().getActiveSheet()).
Fixed how my values were organised (into arrays within arrays)
Googled the error message and looked at how to properly getRange/setRange in the documentation and in tutorials. Apparently you cannot set arbitrary cells if you are calling them from the excel sheet itself. This is my suspicion as to what is going wrong here. However how can this be the case if when I put in a simple string it functions fine. I am simply doing string interpolation here.
I know this is rudimentary stuff, any help would be appreciated.
Removing both brackets and quotation marks should make it work
Modification:
cellsToWriteTo = `R${firstRow}C${firstColumn}:R${firstRow}C${firstColumn + 2}`
Execution:
Output:
I am working on a project where I take multiple column/row inventory sheets and turn them into a multi-row/2-column format for order picking.
I have a switch for selecting the appropriate inventory sheet and a map() function that copies the imported information from the inventory DataRange().
However, not all the data is in consistent columns. What I would like to do is find an expression that maps the next column in if the column it was mapping has a zero or "" value.
I won't give you the full body of code unless you need it, but hopefully just the important parts.
This is what I have:
var source = SpreadsheetApp.openById("1xixIOWw2yGd1aX_2HeguZnt8G_UfiFOfG-W6Fk8OSTs"); //This sheet
var srcSht = SpreadsheetApp.getActive();
var sourceMenu = srcSht.getRange('A1');//This is the cell cotaining the dropdown
var menuTest = sourceMenu.getValue();
// Variable for the vars sheet. If it doesn't exist, create it
var varsTest = source.getSheetByName('vars');
if (!varsTest){source.insertSheet('vars');}
var importedA1 = varsTest.getDataRange().getA1Notation();
varsTest.clearContents();
var t1Imp = '=ImportRange("test1_Id", "Stock!A1:F11")';
var varsData = varsTest.getRange('A1');// This is the cell we fill with the importRange formula
varsData.setValue(t1Imp);
var imported = varsTest.getDataRange().getValues();
var newOrder = imported.map(function(item) {
if (item[4] !== NaN){return [[item[0]],[item[4]]];};
if (item[4] === NaN){return [[item[0]],[item[3]]];};}
var orderRange = source.getSheetByName('Sheet1').getRange(10,1,newOrder.length, newOrder[0].length);
orderRange.setValues(newOrder);
Logger.log("\t" + newOrder);
Logger.log(newOrder):
[(timestamp omitted)] items1,order,caramel,6,c&c,2,mint,3,PB,0,,,items2,,caramel,,strawberry,,mint,,PB,
It seems to be skipping the if statements, or I told it that I mean to test the index as NaN, which will obviously never be true.
I also tried replacing 'NaN' with 'undefined'. Same result. I tried finding the item[4].Values, but it gave me an error. I also tried the same logic using filter() instead of map() but it copied the entire data set.
I pull these values onto a new 'vars' sheet in the workbook (to minimize calls to the web service):
test1
reduce them to the first and last columns, then output:
test
The cells in the 'order' column for the second set of items in the 'test' sheet are blank. The values for that order column should be in item[3] of that array, but I can't get the script to identify that that the blank cells are blank.
I am new to Google Apps Script and JS, but I am watching a lot of tuts and learning by doing. If I find a solution, I will post it.
Thank you StackOverflow, I could not have learned as much as I have without this community!
I have a working function that does what I want. In short:
I had to create a duplicate of the order column in a new column, so that all the values would line up. It's not technically a JS answer, but was the simplest and follows good spreadsheet rules.
function rmZeroOrderPS(item){
var source = SpreadsheetApp.openById("<sheetId>"); //This sheet
var varsTest = source.getSheetByName('vars');
var imported = varsTest.getDataRange().getValues();
var i=-1;
while (i <= imported.length){
if(item[8]!= 0) {return [item[0],item[8]]};
i+=1;
};
Update 2: It was a permissions issue. I guess I have to duplicate all my scripts for each spreadsheet? Also I'm updating my code now that I've fixed it.
Update: my code is wrong (I need to drop the second for loop I think) but my question is why the script isn't running on my sheets.
I'm trying to write data to columns in a spreadsheet. Maybe I'm just having permissions issues?
This is my first time using Google scripts and I'm not familiar with JavaScript either. I have a spreadsheet with a lot of data and I successfully removed duplicates as defined by comparing the first two columns--no bugs, no issues, ran successfully first try. Now I'm trying to fill in data on two new, empty columns.
If column 2 is in the format "foo - bar", I want column 3 to be "foo" and col 4 "bar". So I wrote this script:
function parseTypes() {
var sheet = SpreadsheetApp.getActiveSheet();
var data = sheet.getDataRange().getValues();
var newData = new Array();
for (i in data) {
var row = data[i];
var str = row[2];
var strSplit = str.split(" - ");
row[3] = strSplit[0];
if (strSplit[1] == "" || strSplit[1] == null || row[4] == undefined) {
row[4] = "";
} else {
row[4] = strSplit[1];
}
newData.push(row);
}
sheet.clearContents();
sheet.getRange(1, 1, newData.length, newData[0].length).setValues(newData);
}
I debugged in and the string array strSplit is accurately being set to "foo,bar". My issue is that it's not actually writing the data to my spreadsheet. I don't know if it's my code or if I'm just running the script wrong because I barely know what I'm doing.
JavaScript use 0 based indexes but SpreadsheetApp use 1 based indexes. This means that row[2] returns the value of column C not column B.
You don't have to copy the script. The only thing you need to change is not using the SpreadsheetApp.getActiveSheet, but you have to use the SpreadsheetApp.openByUrl('https://blalaallla').getSheetByName('blalala') method. This way you don't have to copy it. Hope this helps.
I've been working on this script in Google Apps Script for a little while now and think I've got it almost figured out. I could really use another pair of eyes though, as it hasn't yet worked to completion.
What I'm trying to do:
I'm working on a sheet dealing with tentative and actual dates. These two dates are in adjacent columns. Once the "actual" date gets filled into its cell, I would like the "tentative" date to be deleted.
Here is my script thus far:
function onEdit() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[0];
var range = sheet.getRange('F4:F');
var range2 = sheet.getRange('E4:E');
var rule = range.getDataValidation();
if (rule != null) {
var criteria = rule.getCriteriaType();
var args = rule.getCriteriaValues();
var clear = range2.clear({validationsOnly: false});
}
}
What do I need to do to get this script running?
It appears you want to delete the value in column E if column F was filled. If so, I don't see the need for dealing with data validation rules. The following script checks that the edited cell is in column F, row >= 4, and that the new value in the cell is a date. If these conditions hold, it clears the cell to the left (using offset).
function onEdit(e) {
if (e.range.getColumn() == 6 && e.range.getRow() >= 4) {
if (e.range.getValue() instanceof Date) {
e.range.offset(0, -1).clear();
}
}
}
Note: this script uses the event object passed to onEdit function. Interestingly, its "value" property turned out to be not useful here, because it is not a date object even when a user enters a date. This is what I use e.range.getValue() instead.