Duplicate Sheet with Name of Cell Value - google-sheets

I am wondering if there is a way to duplicate a sheet I am working on and assigning that new duplicate sheet a name based on a cell value in the original sheet?
Right now I am simply using a script/button to clear content of cell values to start a new stock order (see below)
function newSalesOrder() {
var activeSheet = SpreadsheetApp.getActive();
var ranges = ["StockOrder!B4", "StockOrder!E8", "StockOrder!D9","StockOrder!A12:B41"];
for (var i = 0; i < ranges.length; i++) {
activeSheet.getRange(ranges[i]).clearContent();
}
}
So I would like to add the ability to duplicate the StockOrder! sheet, rename it to the Purchase Order Number value in Cell C4 for example.

If I understand correctly what you are trying to achieve, all you need to do is:
Save the content of a given cell into a String variable
This one is a bit tricky, the hierarchy in Google sheets is: SpreadSheet: Sheet: Range: Cell. So what you need to do to get the value of Cell C4 is:
var ss = SpreadsheetApp.openById('Insert ID here');
var name = ss.getName();
var sheet = ss.getSheetByName('Insert Sheet Name Here');
var range = sheet.getRange(3,4);
var newSheetName = range.getValue();
Of course, you do not need to use openById or getSheetByName methods. You can use getActiveSheet() or whatever you like.
Create a new sheet whose title is the saved String variable
var newSpreadSheet = SpreadsheetApp.create(newSheetName);
Hope this is gonna help:)

Related

Google Sheets IMORTHTML converting to scientific notation

I am importing a table to google sheets with a formula like:
=IMPORTHTML("http://TheServer/FetchBatchData.php,"table",1)
In a web browser I get data that looks like the following:
Batch Batches Mix Customer Status
30DE 3 AGPDHIGH Joe Sent
30DF 3 KHM100 Nancy Sent
30E0 1 DEER100 Bob Sent
30E1 3 KHM100 Ted Sent
My problem is that Google Sheets converts the Batch data (a simple Hex value) to scientific notation when it sees the "E" in the batch. The result is that "30E0" becomes 30 and "30E1" becomes 300. I have tried changing cell formats with no luck. Is there something that I am missing in setting up the formatting or the formula that can get Google to not help me?
I made several tests using formulas. The values like "30E0" are always taken and calculated automatically, even with the fix in the comments.
Because of that, the only way I found to fix the issue was to create a custom formula that takes the values of the HTML and returns plain text automatically, which will fix the issue.
The custom formula was created based on the URL in the sample sheet "https://ex1.svfeeds.com." However, you can change it to the correct one.
Here is the sample code:
function parseXml() {
// URL where the data is located and calling the URL fetch services.
let url = "https://ex1.svfeeds.com/";
let xml = UrlFetchApp.fetch(url).getContentText();
let document = XmlService.parse(xml);
let root = document.getRootElement();
// path to reach the raw data
let body = root.getChild('body');
let table = body.getChild('table');
let tbody = table.getChild('tbody');
let rows = tbody.getChildren('tr');
// empty variable, it will be updated with the new array
// with the data of the table
let tableData = [];
// starts the for loop to each of the rows and columns of the HTML table
for (let i = 0; i < rows.length; i++){
var columns = rows[i].getChildren('td');
if (columns.length == 0){
columns = rows[i].getChildren('th');
}
// empty variable, it will be updated with the new array
// with the information in the rows
var rowValues = []
// new "for" that will call the values in each cell in the table
for (var j = 0; j < columns.length; j++){
var cell = columns[j].getValue();
// push the cell values to the rows
rowValues.push(cell);
}
// push the values to the complete table
tableData.push(rowValues);
}
return tableData;
}
After that, you can call the custom function by adding =parseXml() to A1 for example, like this:
And it will look like this:
The path of the values use in this sample code, can be change base on how is the information is place in the original link. For example for the current page we use these variables to get to the raw data:
// path to reach the raw data
let body = root.getChild('body'); // 1
let table = body.getChild('table'); // 2
let tbody = table.getChild('tbody'); //3
let rows = tbody.getChildren('tr'); //4
and
columns = rows[i].getChildren('th'); //5
Base in the HTML source:
Reference:
Apps Script XML Service.
Custom Formulas.
Let me know if you have further questions.
I found a workaround though it is not something that I really like. Since the google Sheets are the only thing currently reading this table, I prepended a single quote to the output, so the 30E1 data becomes '30E1, and that will get me by until I can get Google Sheets to stop reformulating the data.
I'm still interested in more better if anyone has it.

How can I copy data from one google sheet to another? (in Appscript)

I would like to move data from one G-sheet to another not using importrange.
How can I do this in Appscript?
Use
var ssheet = SpreadsheetApp.openById(SPREADSHEET_ID)
var sheet = ssheet.getSheetByName(SHEET_NAME)
var values = sheet.getRange(RANGE_NOTATION).getValues()
and in your main sheet
var ssheet = SpreadsheetApp.getActiveSpreadsheet()
var sheet = ssheet.getSheetByName(SHEET_NAME)
sheet.getRange(RANGE_NOTATION).setValues(values)
then delete the original
From the main sheet from where you want to extract data,use something like this :-
var ss = SpreadsheetApp.openById(ID_of_sheet) var ssname = ss.getSheetByName(Name_Of_that_particular_Sheet_in_theSpreadSheet) var DataCopied = ssname.getRange('A1:B').getValues() // "A1:B is an example StringNotation of that range from where you want to copy the data"
Now you have extracted the data from that sheet, use this to paste it on another sheet
var ss = SpreadsheetApp.openById(ID_of_Secondsheet) var ssname = ss.getSheetByName(Name_Of_that_particular_Sheet_in_theSpreadSheet) // where you want paste the data ssname.getRange('A1:B').setValues(DataCopied) // setValues will paste the data you copied.
Make sure to use the same rangeNotation which you've used while copying the data from main sheet.
For more information, you can refer to documentation :- ServiceDoc

Make the column values static in Google sheets

I have two columns in google sheets. 1st column column A is the input column and the second column column B is the output column. I want the values in the second column to be static once I enter the values in the 1st column. (as the results in the second column are based on the values entered in the first column)
Here is a basic script that takes the value to the right of the edited cell and makes it "static":
function onEdit(e) {
var staticCell = e.range.offset(0,1); // Finds the cell to the right of the edited one
var staticVal = staticCell.getValue(); // Gets the value of that cell
staticCell.setValue(staticVal); // Sets the cell value to itself, removing the formula and making the cell "static"
}
Here is another script that does the same thing, but only works when column A is edited (specific to this question):
function onEdit(e) {
var staticCell = e.range.offset(0,1);
var staticVal = staticCell.getValue();
if(e.range.columnStart == 1){ // Checks to see if the edited cell is in column A
staticCell.setValue(staticVal);
} else {}; // If it is not in column A, nothing happens
}

Newbie: writing a script for google sheets that will run on all sheets

I am a real novice at this (not even). Have never written code in my life-just copied the following code off a website that explained how to do it. I a google doc that I need to be sorted according to Column C continuously as new data is added. This is the code I was given:
function onEdit() {
var sheet = SpreadsheetApp.getActiveSheet();
var range = sheet.getRange(3, 1, sheet.getLastRow() - 2, sheet.getLastColumn());
range.sort({column: 3, ascending: true});
}
It works partially, but I need it to be applied to all sheets/tabs in the document.
Thanks in advance!
Your code includes the line var sheet = SpreadsheetApp.getActiveSheet(); and the rest of you code is based on sheet - so it run only on one sheet, the one that is active when new data is inserted, so the one in which the edit is performed
If instead you want to perform the sorting on each edit in all sheets of the spreadsheet, you need the method getSheets() to retrieve all sheets of the spreadsheet as an array
Subsequently you need to loop through the array to apply the sorting function to each sheet
Sample:
function onEdit() {
var sheets = SpreadsheetApp.getActive().getSheets();
for (var i = 0; i < sheets.length; i++){
var sheet = sheets[i];
var range = sheet.getRange(3, 1, sheet.getLastRow() - 2, sheet.getLastColumn());
range.sort({column: 3, ascending: true});
}
}
Important:
The onEdit trigger only detects human-made edits like typing of text. If instead you want to fire the trigger on changing the document structure, such as e.g. inserting a new empty row (which is different from typing values into cells of an alreday existing empty row), you would need to replace the onEdit trigger, through the installable onChange trigger, see also here

How to use value of a cell once?

I have a certain cell (e.g. C1) that is computed by some formula and another cell (e.g. C2) that when a IF event happens, it takes the value of cell C1.
But, I only want to have C2's value be calculated one initial time and from then on, C2's value will stay the same and no longer depend on C1.
Is that possible, and if so, how can I do that?
If I wasn't clear enough, here is an example spreadsheet with the logic commented.
Found the answer: a simple copy script can do the job:
function simpleCopy() {
var sheet = SpreadsheetApp.getActiveSpreadsheet(); //access to the spreadsheet
SpreadsheetApp.setActiveSheet(sheet.getSheetByName('testing enviroment')); //access to the sheet by name
var range = sheet.getRange('D1'); //assign the range you want to copy
var copy = range.getValues();
sheet.getRange('D2').setValue(copy) //new range you want to paste a value
}

Resources