Unmerge in Google Apps Script - google-apps-script

I'd like to unmerge all the cells of my google spreadsheet using script. I believe that VBA has this option (cells.unmerge) but I can't find a similar operation in GAS. I've tried this script but it didn't seem to work.
function MyFunction() {
var Sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var Range = Sheet.getDataRange().activate();
Range.clearFormat();
}

The correct word is "Range.breakApart" not "unmerge". Note that this only works when the range it is called on encompasses all merged cells.

Try this code:
function unmerge() {
var app = SpreadsheetApp;
// get current active sheet use single line coding
var activeSheet =app.getActiveSpreadsheet().getActiveSheet();
// get last row
var lstrow= activeSheet.getLastRow();
// see below description **
var mergerange = activeSheet.getRange(13,4,lstrow).getMergedRanges();
for (var i = 0; i < mergerange.length; i++) {
Logger.log(mergerange[i].getA1Notation());
Logger.log(mergerange[i].getDisplayValue());
mergerange[i].breakApart();
}
}
** 13= start row number. 4 = column number of merge cells.

Related

Apps script copy multiple range from 1 sheet to another spreadsheet

I am trying to copy data from 1 spreadsheet to another, I have successfully implemented something i found online that works with a specific range
function cloneGoogleSheet() {
// source doc
var sss = SpreadsheetApp.openById("spreadsheetkey1");
// source sheet
var ss = sss.getSheetByName('_tab_name_source');
// Get full range of data
var SRange = ss.getRange(7,3,5,1);
// get A1 notation identifying the range
var A1Range = SRange.getA1Notation();
// get the data values in range
var SData = SRange.getValues();
// target spreadsheet
var tss = SpreadsheetApp.openById("spreadsheetkey2");
// target sheet
var ts = tss.getSheetByName('tab_name_destination');
// Clear the Google Sheet before copy
//ts.clear({contentsOnly: true});
// set the target range to the values of the source data
ts.getRange(A1Range).setValues(SData);
};
The above piece coding work perfectly however I need to copy 18 different ranges that i cant just merge into 1 range. I considered the option of using the above however "multiplying" it 18 times for each range that however seems like a very inelegant solution.
I found a working solution that works if it stays within the same spreadsheet since it uses copyto instead of get/set values. The values part works perfectly since it doesnt mess with merge cells formatting. I have been struggling past 2-3 hours in merging the below-working code with elements from the first code to make a working script.
function test () {
try {
var spread = SpreadsheetApp.openById("spreadsheetkey");
var sheet = spread.getSheetByName("tab_name_source");
var rlist = sheet.getRangeList(["c7:c11", "g7:g11", "k7:k11"]);
sheet = spread.getSheetByName("tab_name_destination");
for( var i=0; i<rlist.getRanges().length; i++ ) {
var r1 = rlist.getRanges()[i];
var r2 = sheet.getRange(r1.getA1Notation());
r1.copyto(r2);
}
}
catch(err) {
Logger.log(err);
}
}
I tried initially to adapt the 2nd piece of coding to using setvalues however i had not been able to succesfully implement the part of getvalues within the scope of this code. I figured once I got this piece of code working with get and set values instead of Copyto i would only need to add the spreadsheetid of the other spreadsheet to get the final result
Try this:
function myFunction() {
var sourceSS = SpreadsheetApp.getActiveSpreadsheet();
var sourceSheet = sourceSS.getSheetByName("sheetname");
var targetSS = SpreadsheetApp.openById("spreadsheet id here");
var targetSheet = targetSS.getSheetByName("Sheet1");
var ranges = ["C7:C11", "G7:G11", "K7:K11"];
ranges.forEach(range => {
var data = sourceSheet.getRange(range).getValues();
targetSheet.getRange(range).setValues(data);
})
}
Source sheet:
Destination sheet:
References:
setValues()
getValues()

Get notes from a cell and insert into another cell

I have a range of cells in Google Sheets, some of them have notes attached.
If there's a note attached to a cell, I need to put the note in a separate cell, and put the location of that note in another cell.
I found this script elsewhere:
function getNote(cell)
{
var ss = SpreadsheetApp.getActiveSpreadsheet();
var range = ss.getRange(cell)
return range.getNote();
}
but when I try to use it I get an error "Exception: Range not found (line 12)."
But this script only gets me halfway there as it only gets the note and puts it in a cell. I also need to know what cell the note came from.
Any help is greatly appreciated.
In the script above the function getNote() expects the paramter cell
If you just run the script without calling getNote() from another function / an environment where it gets a values for cell assigned, the script will fail wiht the error you obtained.
Indeed, this script doe snot not meet your needs. What you probably want is to screen all your cells for the one that have notes.
What you need to decide is into which cells you want to put the note and the cell notation.
Below is a sample that you need to adapt for your needs:
function getNotes() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
//if you have only one sheet in the spreadsheet, otherwise use ss.getSheetByName(name);
var sheet = ss.getActiveSheet();
var range = sheet.getDataRange();
var results = range.getNotes();
for (var i = 0; i < results.length; i++) {
for (var j = 0; j < results[0].length; j++) {
//if a not empty note was found:
if(results[i][j]){
var note = results[i][j];
var cell = range.getCell(i+1, j+1);
var notation = cell.getA1Notation();
//adjust the offset as function of the column / row where you want to output the results
cell.offset(0, 1).setValue(note);
cell.offset(0, 2).setValue(notation);
}
}
}
}
Important references:
getNotes()
getA1Notation()
getDataRange()
getCell(row, column)
offset(rowOffset, columnOffset)

onEdit(e) DriveApp.getFileById

Having issues getting the following to work.
The intent was on edit to push information from the specific cell or cells of active sheet to specific cells on a separate worksheet.
Note: I am new to google sheets
function onEdit(e) {
var source = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Working");
var cell = source .getActiveCell();
if (cell.getRow() == 9 && cell.getColumn() == 2) {
var target = DriveApp.getFileById("1biaIVlafaNQTHjtR8ctASCpDmC2O1wwfJfAUCmzIztI")
.getSheetByName("Master_Sheet");
target.getRange("A1").setValue(cell.getValue());
}
}
The reason it does not work is because you are using onEdit(). This is a simple trigger that will fire off whenever you edit the sheet. Since simple triggers cannot perform operations that require authorization you are limited to working only in the Spreadsheet and cannot access any other files.
Read up on restrictions here
I am now able to push information to the target sheet using the following code.
function myFunction() {
var sourceSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Source");
var sourceData = sourceSheet.getRange("A3:C3").getValues();
sourceData.splice(0,1); // Remove header
var targetSS = SpreadsheetApp.openById("1pyJzZ86WDh2FNXFufUAt2SkAUod32i7AzvG0EKmnvEU").getSheetByName("Destination");
var targetRangeTop = targetSS.getLastRow(); // Get # rows currently in target
targetSS.getRange(targetRangeTop+1,1,sourceData.length,sourceData[0].length).setValues(sourceData);
};

Google Spreadsheet Script - How to split an Object[][] from .getValues?

I want to importxml from more than 50 sites in Google Documents and fill that information into another sheet and preferably overwrite the data already there preventing a clear function. The problem I'm running into however is I'm getting
={229999999.99;0;0;183000000;169999999.99;209999999.99}
in one cell. How do I split this to be six numbers in different columns but the same row?
This is my code:
function Xml() {
var sheet = SpreadsheetApp.getActiveSpreadsheet();
var s = sheet.getSheetByName('Script');
var ss = sheet.getSheetByName('TradeIBuy');
var Num = Browser.inputBox("How many URLs to scrape");
for (y=0;y<2;y++) {
for (x=2;x-2 < Num;x++) {
//ss.getRange("b4:n400").setValue(""); //Too slow for spreadsheet
var url = s.getRange(x,1).getValue(); //Grab URL
s.getRange(2,6).setValue(url); //Move URL into position
var xpathResult = s.getRange("F3:F8").getValues(); //Grab results from first sheet
if (y===1){
var export = ss.getRange(x+2,2); //Export position
export.setValue(xpathResult); //Export data to second sheet
SpreadsheetApp.flush();
}
}
}
}
function clear() {
var sheet = SpreadsheetApp.getActiveSheet();
sheet.getRange("a2:b1000").setValue("");
}
Thanks ~ Chandler
If I understand your question properly, I think there's a solution without scripting.
=SPLIT(SUBSTITUTE(SUBSTITUTE(ImportXML(blah,blah),"}",""),"{",""),";")
...will change {229999999.99;0;0;183000000;169999999.99;209999999.99} to:
229999999.99 0 0 183000000 169999999.99 209999999.99
... with each number in its own cell.
SPLIT breaks a string at the given delimiter character, which is ; in this case.
SUBSTITUTE is being used to strip the braces.

is it possible to use getRowsData without a range?

I am using Google app scrips and I want to iterate through a spreadsheet that will be updated weekly. (this is why i dont want to set a range i want to be able to iterate through the entire sheet.)
Is this possible? If yes can you give an example of how this would be done?
and if this isn't a good idea, why not?
Thank you!
Example code
function doGet(e){
var ss = SpreadsheetApp.openById('key in here');
var sheet = ss.getSheetByName("Form Responses");
var range = sheet.getRange(1,1);
var dataRange = range.getValue().toString();
app.add(app.createHTML("There are " + dataRange + " posts today"))
return app;
Something like this, but I want to be able to see the whole sheet not just the range
Henrique Abreu and Srik provided you with correct answer - getDataRange on sheet should serve your purpose.
function doGet(e){
var sheet = SpreadsheetApp.openById('spreadsheetId').getSheetByName('sheetName');
var data = sheet.getDataRange().getValues();;
...
}
data is now 2-dimensional array, you can iterate through it, get last column/row containing content etc. Please read through class reference here: https://developers.google.com/apps-script/reference/spreadsheet/sheet
You cannot iterate over the sheet by itself, but always iterate over the vales of range.
However you don't have to use a fixed range but can compute the range at every script execution.
To do this you could use getlastcolumn() and getLastRow().
This two methods return the last column or row with content in it.
A commodity method is getDataRange() which directly gives you the range with data in it.
Every script execution this range will extend over all your cells and columns with content.
Look at the example from Google API documentation:
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[0];
// This represents ALL the data
var range = sheet.getDataRange();
var values = range.getValues();
// This logs the spreadsheet in CSV format with a trailing comma
for (var i = 0; i < values.length; i++) {
var row = "";
for (var j = 0; j < values[i].length; j++) {
if (values[i][j]) {
row = row + values[i][j];
}
row = row + ",";
}
Logger.log(row);
}
Hope that helps.