I'm trying to get value from a cell with a type "Time".
In the sheets it's look like just: "15:40" (filled manually)
If I use getValue() from this cell, and setValue to another cell it will be no problem.
But when i'm trying to manage some parsing with regexp i'm getting an error like:
TypeError: Can't find a function match in object "Sun Dec 31 1899 05:22:00 GMT+0300 (MSK)."
Here is the code itself, it's simple:
...
var sheet = SpreadsheetApp.getActiveSheet();
cell = sheet.getRange(1, 1).getValue();
cellpart = cell.match(..:..);
...
Debug says that type im getting not a "String", but "Data" and its value is in the double quotemarks in the errormessage above.
How can i get a string value from the cell? Looks like simple, but i spent all night trying to get whats wrong. Any Help will be appreciated.
To make your data into a string you can use .toString()
cell.toString().match(..:..)
Note that cell is a Date object. That's why it doesn't support .match, but you can make it into a string, which will make it the string value "Sun Dec 31 1899 05:22:00 GMT+0300 (MSK).".
I have also run into this problem when creating a mail merge from sheets. I have not had the need to match/ search through these values but the first step in this process is to get the data into a format that you want. After that you can rewrite it back to the cells or process from there.
Below is my method to transfer the date format, then write the values into an array in the format I need. This effectively removed all of the extra garbage date information. Once I had a clean dates, I was able to manipulate that data without a problem.
var rawSubmitDate = sheet.getRange((i+2), 1, 1, 1).getValue();
var submitDate = Utilities.formatDate(rawSubmitDate, "PST", "MM/dd/yy");
This first portion was used with a loop of the rows with data. You can see I use .formatDate() to set the long data form into what I want. You can find more information on how to format the way you need in the GAS reference as well as online on the syntax of date formats.
var lastColumn = sheet.getMaxColumns();
var dataRow = sheet.getRange((i+2), 1, 1, (lastColumn - 2));
var dataArray = dataRow.getValues();
dataArray[0][2] = whenA;
dataArray[0][25] = whenB
dataArray[0][37] = whenC;
dataArray[0][40] = whenD;
dataArray[0][43] = whenE;
dataArray[0][46] = whenF;
In this section I create an array of all of my values and write my cleaned dates into that array. The [] values are defined by their column index in my row. For instance, the 26th row contained a date that needed to be reformatted (whenB). These dates were things like DOB, time of incident, etc.
I have not written code to place these values back into the sheet because I use QUERY() functions to populate the sheet I pull from. Writing values into the cells involved in a QUERY() will throw an error. The process however would require a nested loop. The outer loop cycles through rows and the inner loop cycles through the column cells in the row writing each data array value. Outer loop index would be defined by the number of rows you have; Inner loop index would be defined by the number of columns you have.
Try using getDisplayValue( instead of getValue(. This will return the cell value as it appears rather than the underlying Date value.
This is the best way I have found to extract a Duration (inserted from a Google Form) without all the gobbledygook inherent in a Date value.
Related
I'm working on an app/sheets combination scoring system for a tournament. The current data in the Firebase database is stored under a tag like so: tag:"[\"Test\",-1,12,3]"
The data is in the form of a list containing a single string and 3 numbers. Each index in the list will be stored in consecutive cells so referencing the data is easy. The difficulty I am having is formatting the data from the sheet to write it to the database in the same format.
Using JSON.stringify doesn't quite give me what I'm looking for:
var range = sheet.getRange(22,24,4,1);
var data = JSON.stringify(range.getValues());
result:
tag:"[[\"Test1\"],[70],[0],[18]]"
This is not quite the same as the rest of the data as I'm turning the entire range to a string by using stringify, but I don't know of a way to format the data to be stored as [string, int,int,int]. I am new to app scripts and java (hence my lack of knowledge of functions) and was hoping somebody knows of another way to write the range of cells to match the data stored in the database.
First thing, Google Apps Scripts uses JavaScript, not Java.
Second thing getValues() returns a Array of Arrays where each inner Array has the values of a row from the corresponding range. In order to get what you are looking for you have to flatten the result of getValues(). One way to do this is this:
var range = sheet.getRange(22,24,4,1);
var data = JSON.stringify(range.getValues().map([value] => value));
var values = [["Test1"],[70],[0],[18]];
var data = JSON.stringify(values.map(([value]) => value));
console.info(data)
This question already has an answer here:
getvalues() returns a complete date in the year 1899 for a cell containing only time
(1 answer)
Closed 3 years ago.
I have a problem i need some help with.
I am using a function (which i found on elsewhere this site) to loop through all my spreadsheet rows to replace the word "undefined" with a blank space ( " " ).
The code works fine, but it seems to also reformat the dates from mm/dd/yyyy format to a text string, due to a .toString method in the code.
I do not want the date (or numbers) reformatted, but I haven't found a way to rewrite my code without the .toString method.
Would anyone know of a way i can replace text in Google Sheet without having to format it to a string first?
Here is the code below. I appreciate any help on this.
function replaceInSheet(sheet, to_replace, replace_with) {
var Data = SpreadsheetApp.getActiveSpreadsheet(); // DATA spreadsheet
//get the current data range values as an array
var values = Data.getDataRange().getValues();
//loop over the rows in the array
for(var row in values){
//use Array.map to execute a replace call on each of the cells in the row.
var replaced_values = values[row].map(function(original_value){
return original_value.toString().replace("undefined","");
});
//replace the original row values with the replaced values
values[row] = replaced_values;
}
//write the updated values to the sheet
Data.getDataRange().setValues(values);
}
You want to replace the string of "undefined" to "" for the cells of Spreadsheet using Google Apps Script.
You don't want to affect the cells which have no value of "undefined".
If my understanding is correct, how about this answer? Please think of this as just one of several possible answers.
For example, as one of several workarounds, how about using TextFinder? When TextFinder is used, the cells which have no value of "undefined" are not affected. In this case, please modify your script as follows.
Modified script:
function replaceInSheet(sheet, to_replace, replace_with) {
var Data = SpreadsheetApp.getActiveSpreadsheet();
Data.getDataRange().createTextFinder("undefined").replaceAllWith("");
}
References:
createTextFinder(findText)
replaceAllWith(replaceText)
If I misunderstood your question and this was not the direction you want, I apologize.
I am trying to find a way to only getValue() of a specific number of characters in a cell/range. For example:
I'm looking at this data in a cell= 4/17/2019 10:15:48
I want to take that data and compare it to another data to determine if it is today or not. The issue is I don't care if it's 10:15:48. I just want to know if it was done on 4/17/2019.
Is it possible to getValue of the cell, but only take the first 9 characters instead of the entire cell data.
Thank you for your help in advance.
For example, it supposes that the value of 4/17/2019 10:15:48 is put in a cell "A1" of the active sheet. In this case, how about the following sample script? I thought that when the value retrieved by getValues() is a date object, the result you want cannot be retrieved. So in this modification, I used getDisplayValue() for retrieving the value.
Sample script:
var sheet = SpreadsheetApp.getActiveSheet();
var value = sheet.getRange("A1").getDisplayValue();
var res = value.substr(0, 9);
Logger.log(res)
Note:
If you want to retrieve values from several cells, you can also use getDisplayValues().
References:
getDisplayValue()
substr()
If I misunderstood your question, I apologize.
I have a data table that I am trying to filter based on the date in one column. I would like to filter the data based on the lastModified column having a date one year or older but even getting it filter on some hard coded date would be a good start. The data in in string format so I am trying to use the new Date() function to convert to date.
var table = $('#database').DataTable( {
fixedHeader: true,
data: dataSet,
columns: [
{ data: "processName" },
{ data: "processLob" },
{ data: "processOwner"},
{ data: "RiskReviewer"},
{ data: "lastModified"}]
} );
var filteredData = table
.column( { data: "lastModified"} )
.data()
.filter( function ( value, index ) {
return new Date(value) < 2015-10-10 ? true : false;
} );
First thing you are going to want to do is add "columnDefs" object for your date column and specify it's type as "date". DateTables has built in date parsing as long as you are following a well known format. ColumnType API Def
If that doesn't get you there completely then you will want to define a render function for your data column on the new columnDef object you just created. There you can check the render type and return a "nice" value for display and raw data value (ideally a value of type Date) for everything else. Render API Defintion
Also some general advice don't try to fight the library. It actually is extremely flexible and can handle a lot. So use the built in API functions where ever possible. Usually things go awry when people try to manipulate the table manually using JQuery. Under the covers the DataTables plugin maintains a ton of state that never makes it to the DOM. Basically if there is a function in the API for it, use it.
EDIT: Adding answer to the original posters question even though he found another solution.
One thing to keep in mind is that "filter" is intended only to give you back a filtered data set. It will not change the display in the grid. Instead you will want to use "search" on the "column()" API item to filter the displayed rows in the DataTable.
There is a small problem with that however. The search method only accepts regular values not functions. So if you want to implement this you have supply a custom search function like so:
// The $.fn.dataTable.ext.search array is shared amongst all DataTables and
// all columns and search filters are evaluated in the order in which they
// appear in
// the array until a boolean value is returned.
$.fn.dataTable.ext.search.unshift(function(settings, data, dataIndex) {
// Using a negative value to get the column wraps around to the end of
// the columns so "-1" will always be your last column.
var dateColumn = $(this).column(-1);
// We get the data index of the dateColumn and compare it to the index
// for the column currently being searched.
if(dateColumn.index() !== dataIndex) {'
// Pretty sure this indicates to skip this search filter
return null;
}
var columnSearchingBy = $(this).column(dataIndex);
// Allows the data to be a string, milliseconds, UTC string format ..etc
var columnCellData = new Date(data.lastModified);
var valueToSearchBy = new Date(columnSearchingBy.search.value);
// Ok this is one of the worst named methods in all of javascript.
// Doesn't actually return a meaningful time. Instead it returns the a
// numeric value for the number of milliseconds since ~ 1970 I think.
//
// Kind of like "ticks()" does in other languages except ticks are
// measured differently. The search filter I am applying here is to
// only show dates in the DataTable that have a lastModified after or
// equal the column search.
return (valueToSearchBy.getTime() >= columnCellData.getTime());
});
// So this should use our fancy new search function applied to our datetime
// column. This will filter the displayed values in the DataTable and from
// that just a small filter on the table to get all the data for the rows
// that satisfy the search filter.
var filteredData = table
.column({ data: "lastModified"})
.search('2015-10-10')
.draw();
Even though you found another way to go on this one maybe the above will help you out later on.
I am returning a query object from Coldfusion as a JSON string which I then parse into JSON in Javascript. It has a bit of a strange format when I finally log it though.
I am faced with two problems. First, I do not know how to access the lowest element (i.e Arthur Weasley) as I cannot use a number in my selector (response.DATA[0].0 doesn't work because the lowest field name is a number). Second, is there any way to assign the values in the columns section to the fields that are numbered 1, 2 and 3?
What I'm really asking is how do I select my lowest level of data? If that can't be done because of the numbers for field names, how do I change the names to something more fitting?
My data logged:
First entry of first entry of DATA = response.DATA[0][0]
So
name = reponse.DATA[0][0];
trainsThing = response.DATA[0][1];