Insert a cell in google spreadsheet using google apps script - google-apps-script

I am working on a Google spreadsheet. I want to know if there is a way to insert a cell in the spreadsheet using apps script.
Example: Assume there are some data from A2 to Y2.
I want to insert a cell A2 with some data. So now there will be data from A2 to Z2.

This will shift everything from A2 to the right by 1 column, leaving A2 empty and ready to insert the new data.
Do be aware that this will also copy across the formatting of A2.
So make sure any borders etc. are placed on A1 and not A2.
function addNewCell() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
ss.getRange("A2").insertCells(SpreadsheetApp.Dimension.COLUMNS);
}
And if you wish to shift A2 across multiple cells, use a range
ss.getRange("A2:C2").insertCells(SpreadsheetApp.Dimension.COLUMNS);
Obviously this particular code will move them 3 across

I got my answer, there is no way to insert a cell.

There's no function to directly insert a single cell, but we can do a move and write:
Move range A2:Y2 to B2:Z2.
Write the new value to A2.
For example:
function insertCell() {
var sheet = SpreadsheetApp.getActiveSheet();
sheet.getRange("A2:Y2").moveTo(sheet.getRange("B2"));
sheet.getRange("A2").setValue("New");
}

I do not think there is way to insert a cell left/right to a cell. If your cells and address are not dynamic, you can do the following
Get the content on A2-Y2 range and put in an array
Add your new desired value on the array at index 0, I mean the first element of array
Insert the new array values in row 2. I mean A2-Z2.
//Get A2-Y2 in a cellFeed
URL cellFeedUrl1 = new URI(worksheets.get(WSID).getCellFeedUrl() +"?min-row=2&max-row=2&min-col=1&max-col=1").toURL();
CellFeed cellFeed1 = googleservice.getFeed(cellFeedUrl1, CellFeed.class);
//store in an Array
for (CellEntry cell : cellFeed1.getEntries())
{ Array_A2Y2.add(cell.getPlainTextContent()); }
//Add your desired cell Value on the first of that array
//Insert the Array items on the your required row

From my experince using google spreadsheets you can only insert a whole row or column.
This is done by right clicking the row/column and select add row/column and then you can select to add it below/right or above/left.

if you want to write in he spreadsheet, you need to use the Class Sheet , GetRange function.
for example :
mysheet.getRange(1,5,nbrows+BNrows-1,5).setValues(myArray); // my Array concern a column

I was interested in moving a block of data down to create a new (empty) row at the top of my table. Knowing that the data in my top row stared in cell A7 and the last column in my table is Column H, I only move the table columns down leaving the rest of my spreadsheet where it is.
function addNewRow() {
var sheet = SpreadsheetApp.getActiveSpreadsheet();
sheet.getRange("A7:H1000").moveTo(sheet.getRange("A8"));
}

Related

How to combine these two App Script formulas?

If both columns E and K have value in them → then run the function in the column G.
As a regular Sheets formula, it looks like this (it works):
=if(not(isblank({$E12,$K12})),$K12*$E12," ")
I need App Script that does the same.
Why do I need a Script instead of regular formula? Because Arrayformula doesn't allow me to write in the same column, I will need this same script for other similarly made formulas.
1)This one is for checking if cells are blank (E12 and K12):
var isCellBlank = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Copy of Produkti').getRange().isBlank();
if(!isCellBlank) {
iSheet.getRange().setValues();
}
2)This one is for the function I want to run:
function FillFormulas() {
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Copy of Produkti');
var lastRow = spreadsheet.getLastRow();
spreadsheet.getRange("G4").setFormula("=if(not(isblank({$E12,$K12})),$K12*$E12," ")");
var fillDownRange = spreadsheet.getRange(4,7,(lastRow-1)); spreadsheet.getRange("G4").copyTo(fillDownRange);
}
Function onEdit(e) I have in a different file.
Can you help me fill in the first part of the Script (isCellBlank - get.Range i guess)?
And how to combine these two scripts, so that it does the same as regular sheet formula, just for the whole column (like Arrayformula)?
If you could add a hidden column before G you could follow this approach I've explained in this other post:
You could sort it out with hidden columns, and values that expand to the next column in which you'd like to have your result or input your value.
Instead a formula: =B3/B4 you'd have ={",",B3/B4}
So, if you manually insert a value in the right column, the formula in left column won't expand. As an example I've created a very dummy calculator of sides and hypothenuse. In B1 (column B in red would be hidden) I have:
={"","Res: "&(C3^2-C2^2)^(1/2)}
And so on in the next rows. In this picture I've inserted manual values in C1 and C2, so C3 has a result:
[]
1
And another example in another row:
You can test it out here and the extrapolate it to your formulas,
(I've erased the part with "Res. " so the result is an actual number, it was just for easier view in my examples):
https://docs.google.com/spreadsheets/d/1ZaEEGWtLU-LXBmg-xy80Ps_biuYhb8WxZBs0g1tGE00/edit?usp=drivesdk

Create Unique ID from 0 to Upward Google Sheets

I have a sheet where data is being added to the last empty row and inserting the new row between the rows which has already data.
I want to create a Unique Numeric number that will be 0 to upward in sequence. Like we use =IF(B3<>"",B2+1,"").
But when new row is added the formula is missed I want to Add unique number for each row.
Because when you insert the row all values are bonded but when you type anything in newly added row in Col B all the number goes disturb. It should work like timestamp once a number is allotted to specific row data it should not change even new row is inserted within data.
For example If script has assigned number 1 to 7 and new row inserted then it should assign new row a number 8 even new row is inserted with data in col B
Your help will be appreciated
ALTERNATIVE SUGGESTION
If I have understood your goal correctly, you may try this custom script below that you can copy and paste as a bound script to your Spreadsheet file:
UPDATED Script
function onEdit() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var data = ss.getRange("B2:B").getValues().filter(String); //Add the range where data you want to have IDs, on my end, it's B2 and below (B2:B)
var ids = [];
var lastRow;
for(row=0; row<=data.length-1; row++){
ids.push([row]);
}
lastRow = ids.length + 1;
ss.getRange("A2:A"+lastRow).setValues(ids);
}
SAMPLE DEMONSTRATION
The custom function will add IDs starting on the cell A2 and below once you run it for the first time from the Apps Script editor:
When new added data on cell B10 has been entered:
In the top row,
=ARRAYFORMULA({"ID";SEQUENCE(COUNTA(B:B)+0)})
Change 0 to 1 or 2, if you want some blank row offset.

1:Update from Sheet 1 static row to MasterSheet dynamic row 2:Show & Hide columns and rows base on cell value

SHEET 1
A: I want to update changes to my "MasterSheet" with the same mobile dynamic row by clicking the cell G1 or G6 macro buttons.
https://docs.google.com/spreadsheets/d/1ISoV2q9g9L0cwP00eCfcb6k7FJ46C-E7GIOAjZCEZ3A/edit?usp=sharing
B: Hide columns and Show Columns D16
C: Hide rows and Show rows A21
For the first of your doubts, you can simply use a combinaton of getValues() and setValues() to move your data from the source to the destination creating a new row in the destination. The following piece of code has self explanatory comments and will achieve what you are aiming for (same would apply for G6):
function getDynamicRows(){
// Get source sheet
var sheet1 = SpreadsheetApp.getActive().getSheetByName('Sheet 1');
// get values of the row we want to store
var range = sheet1.getRange('B4:Q4').getValues();
// Get destination sheet
var masterSheet = SpreadsheetApp.getActive().getSheetByName('MasterSheet');
// Get range of destination sheet. If we want to append a new row at the end of
// our data we get the last row and add one as that is where the new data will go
// and then set the number of columns the same as the ones from the original source
// Finally just set values to the array of values we got from the source
masterSheet.getRange(masterSheet.getLastRow()+1,1,1,range[0].length).setValues(range);
}

Google Sheets looking for a google script like VLOOKUP but combines the found values and joins them into a specific cell

I have a spreadsheet where I'm trying to add an automatic search function whenever a cell on the Sheet "List" Column 1 gets selected.
It's sort of like using a VLOOKUP function of the sheets but I've been unsuccessful trying to come up with an effective code for it.
Test Spreadsheet link
I made a simple test spreadsheet hopefully for people to easily understand how the sheet should work.
In the 'Database' sheet, there's a list of people with the fruits they like or dislike.
In the 'List' sheet, the list is reversed where the fruits are now the main list but here, when a person clicks on the cells with the fruits, the top cells should automatically update with the combined names of people who like or dislike that certain fruit.
The function should go like this:
If I click a cell on column 1 of the 'List' sheet,
A1 cell updates it's value with the active cell value
B1 cell updates it's value with the combined values based on who likes it from the 'Database' sheet Column 2.
B2 cell updates it's value similar as above but from Dislikes in Column 3
I've attached the code I currently have but I'm not able to get the last 2 steps working.
There is also a guide in the sheets on what the correct answers should look like for each fruit.
I got stuck looking for a way to make the steps 2 and 3 work. I was able to find a code here but it stops after finding one match. stackoverflow.com/questions/10838294/… My current problem is: Since the cells [B2:B] to filter from on the Database sheet has multiple values, is it possible to find all cells with at least a partial match, get the values of the cells on the left of that then list them into the B1 cell on the "List" sheet?
Test Spreadsheet link
Code.gs
function onSelectionChange(e){
var currentsheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var currentcell = currentsheet.getActiveCell();
var activerow = currentcell.getRow();
var activecol = currentcell.getColumn();
var sname = currentsheet.getName();
// Check if current sheet name is correct
if (
sname == 'List'
)
{
// Check if this on first column
if (activecol == 1)
{
// ACTION
var name = currentcell.getValue(); //Get current cell for searching
var prefsheet = SpreadsheetApp.getActive().getSheetByName("Database");
var last = prefsheet.getLastRow();
var data = prefsheet.getRange(1,1,last,2).getValues(); // create an array of data from columns A and B
for(nn=0;nn<data.length;++nn){
if (data[nn][1]==name){break} ;
SpreadsheetApp.getActiveSheet().getRange('A1').setValue('Fruit: ' + name);
SpreadsheetApp.getActiveSheet().getRange('B1').setValue('Like: ' + data[nn][0]);
}
}
};
};
I was able to find a workaround for this and it turns out I didn't have to use a Google Script code to keep updating the formula on List!B1.
I'm new with scripting and sheets but I'll be sharing this formula here in case someone needs something like this in the future.
This is what I used on List!B1
=JOIN(", ",query(filter(Database!A2:B,REGEXMATCH(Database!B2:B,A1)),"Select Col1"))
Regexmatch does the search for partial value and returns as "TRUE"
Filter will then list these rows and query "Select Col1" will only keep the first column of the results and remove the second column. Lastly, Join formula will concatenate them into one cell and add separators.
Which is working very nicely for my purpose. If anyone has any suggestions I'd love to hear about it too.

How to copy row ranges in Google docs?

I have a Spreadsheet, like excel on Google Docs. I am using both Mozilla Firefox and Google Chrome, whichever works. Almost all my columns have dropdown list validation(you know, each cell has a dropdown list to select, I hope I made it clear). I arranged them when I first created the spreadsheet, gave all the columns validation from ranges I created.
My problem is, whenever I add a new row, that row doesn't have any validations, all of them are gone. The old rows still have the validations.
So then, I set the validations every time I add a new row, one by one. This is frustrating. Some people also had the same problem, asked online, but no one answered.
When I copy an empty row with validations and paste it on the new row, it works fine. So, what I am saying is, can you help me write a script for it? Like copying 5 rows when I execute the script?
I am trying to study the scripts but I did nothing nothing so far. I think
var actSc = SpreadsheetApp.getActiveSpreadsheet();
var range = actSc.getRange("A1:B1");
This all I got from the examples I saw. I mean it. I got nothing.
If this copies the ranges of one cell, then I guess I should do it for all my columns.
But how do I put them in the new row? Is there something like setRange?
I could really use some help. This is driving me crazy and I really don't get this script thing.
What I mean by range is that I have ranges like "STATES" and it includes "NY,LA,CA" etc. This NY,LA,CA fills the dropdown list in the cells of that STATES column. I hope this getRange means this range.
Sorry about my English.
If I understand correctly, you want to script a function that will add new rows to a sheet and maintain the existing validations for your columns. This is certainly possible and not too difficult. One approach could be a "refresh validations" function that updates your entire sheet all at once, in the event that you want to reuse it in other sheets. First, though, it sounds like you could use a brief overview of the object classes you need to know about to do basic Google Apps Scripts:
SpreadsheetApp - Think of this class as the foundation of the Spreadsheet Service. It provides file I/O and functionality that is not tied to specific spreadsheets, per se, such as UI and the creation of Data Validation sets. It's the interface to all of your individual spreadsheet documents.
Spreadsheet - A spreadsheet document file, which can contain multiple Sheets. This is what gets created when you create a new Google Sheets document in Drive. Provides document-level functions, such as the ability to manage ownership, set permissions, access metadata, etc. There's some overlap with the Sheet class, so this one can seem like a bit of a mishmash.
Sheet - An individual sheet is what you normally think of as a spreadsheet: a set of rows and columns. Each Spreadsheet document can contain many, distinct Sheets. The Sheet class lets you modify the overall appearance of the sheet. You can freeze or hide rows, protect ranges of cells from being edited, add/delete rows and columns, etc. You can also get data about the sheet, such as the last row that has content or the maximum range of the whole sheet.
Range - Dropping down another level, we reach the Range object, which represents a certain rectangular area of cells. This can be as small as a single cell or as large as the whole sheet. It does not seem possible, however, for Ranges to represent discontiguous cells. This is where you had some trouble, because you treated the Range object as content that you could copy and paste in your sheet, which is understandable. But a Range isn't the data in the cells it represents. It's just an interface to those cells. If you want to access the data itself, you have to drop down to the bottom level of the hierarchy:
Value - The actual contents of your sheets are normal JavaScript values: strings, integers, Booleans, etc. that you can manipulate with the subset of JavaScript that Google Apps Script supports.
In order to do something with the values in your sheet, you first get the Range object from the Sheet (which you get from the SpreadsheetApp) and then get the values from the Range:
var values = SpreadsheetApp.getActiveSheet().getRange("A1:B1").getValues(); // returns [[]]
Note that getValues() returns a multi-dimensional array. As a representation of the values in your sheet, it looks like this:
// row 1 [[column A, column B, column C, column D, ...],
// row 2 [column A, column B, column C, column D, ...],
// row 3 [column A, column B, column C, column D, ...],
// row 4 [column A, column B, column C, column D, ...],
// row 5 [column A, column B, column C, column D, ...], ...]
So if the range A1:B1 is a range of one row and two columns, you can retrieve the values with A1 notation or by specifying the upper left row and column of the range, and the number of rows and number of columns you want to retrieve:
var sheet = SpreadsheetApp.getActiveSheet();
var range = sheet.getRange("A1:B1");
var range = sheet.getRange(1, 1, 1, 2); // row 1, column 1, 1 row, 2 columns
var values = range.getValues(); // returns [[50, 100]]
If the value in A1 is 50, and the value in B1 is 100, the last function above will return [[50, 100]]. You can access individual cell values directly, too:
var range = sheet.getRange("A1");
var value = range.getValue(); // returns 50
var cell = range.getCell().getValues(); // returns [[50]]
Obviously, you can set the values of ranges, too:
var range = sheet.getRange("A1:B2");
range.setValues([[50, 100]]);
range = sheet.getRange(1, 1); // same as sheet.getCell(1, 1)
range.setValue(50); // the value of A1, or row 1 column 1, is now 50
The next step is to figure out how the Data Validation class works. You create a Data Validation object using the Data Validation Builder, which lets you chain together a series of rules to apply to a range. You then set the range to that Data Validation rule set:
var stateList = ["AK", "AL", "AR", ...];
var rules = SpreadsheetApp.newDataValidation() // create a new Data Validation Builder object and use method chaining to add rules to it
.requireValueInList(stateList, true) // first param is the list of values to require, second is true if you want to display a drop down menu, false otherwise
.setAllowInvalid(false) // true if other values are allowed, false otherwise
.setHelpText("Enter a state") // help text when user hovers over the cell
.build();
range.setDataValidation(rules); // apply the rules to a range
Now you can insert rows and the rules should copy over into them automatically:
var lastRow = sheet.getLastRow(); // get the last row that contains any content
sheet.insertRowAfter(lastRow);
Or copy the rules and use them elsewhere:
var cell = sheet.getRange(1, 1, 1, 1);
var rule = sheet.getDataValidation(); // returns rule
var range = sheet.getRange("A1:B1");
var rules = range.getDataValidations(); // returns [[rules, rules]]
var lastRow = sheet.getLastRow(); // or sheet.getMaxRows()
range.setDataValidations(rules);
So you can very easily put these concepts together to write whatever sort of function you need to add rows, build validation rule sets, and add validations to new ranges of cells. You can do most of these things more concisely than I have here, but it sounds like you're looking for a more in-depth explanation. I hope it helps.
var sheetToUpdate = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
sheetToUpdate.insertRowAfter(sheetToUpdate.getLastRow());
var rangeToUpdate = sheetToUpdate.getRange(sheetToUpdate.getLastRow()+1,1,1,sheetToUpdate.getMaxColumns());
sheetToUpdate.getRange(sheetToUpdate.getLastRow(),1,1,sheetToUpdate.getMaxColumns()).copyTo(rangeToUpdate, {formatOnly:true});