Pretty new to coding and I've been trying to solve this one, but I can't find out how and now I'm turing to you guys:
There is a spec sheet, containing a couple of information on an item:
Product Name (on A3)
Product Code (on A4)
Volume (on c3)
Und (on C4)
Cost (on A5), etc.
Then, underneath this "header", there is a table containing the ingredients that make up that item:
ItemNumber, Product, Manufacturer, Unt, Cost, Remarks
These are set on a range (A12:T50)
The need is to have this table moved to a sheet, which the below code does, but how I can I have the header moved as well, repeating each of the header ranges, forming a database-like table for further consulting?
Here is the working script:
function copyrange() {
var sourceSheet = 'New Item';
var destinationSheet = 'Consolidated';
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName(sourceSheet);
var LastRowSource = sheet.getLastRow();
var LastColumnSource = sheet.getLastColumn();
var values = sheet.getRange(11,1,LastRowSource,LastColumnSource).getValues();
var csh = ss.getSheetByName(destinationSheet);
var data = [];
var j =[];
for (var i = values.length-1; i != ""; i--) {
if ( values[i][0] != '') {
data.push(values[i]);
//sheet.deleteRow(i+1)
}
}
//Copy data array to destination sheet
csh.getRange(csh.getLastRow()+1,1,data.length,data[0].length).setValues(data);
}
Here is the link to the file in question:
https://docs.google.com/spreadsheets/d/1GlD_VIOFHj7PGfCCnfVZqdZbE22aVoUw91BSCZecsRc/edit#gid=371161645
Any help is appreciated.
Related
I currently have a script that I use to apply mass changes to multiple spreadsheets
function onOpen() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var menuEntries = [];
menuEntries.push({name: "Update Sheets", functionName: "updateSheets"});
ss.addMenu("Actions", menuEntries);
}
function ChangesAug1() {
var data = SpreadsheetApp.openById('XXX').getSheetByName('ListOfSheetsToBeUpadated').getDataRange().getValues();
for (var row = 2; row < data.length; row++ ) {
var spreadsheet = SpreadsheetApp.openById(data[row][0]).getSheetByName('Template');
And I have this other script I am using to copy and paste a range from one spreadsheet to another
var sss = SpreadsheetApp.openById('SourceID'); //replace with source ID
var ss = sss.getSheetByName('TemplateSheet'); //replace with source Sheet tab name
var range = ss.getRange('A1:EJ5'); //assign the range you want to copy
var data = range.getValues();
var tss = SpreadsheetApp.openById('DestID'); //replace with destination ID
var ts = tss.getSheetByName('DestSheet'); //replace with dest
ts.getRange(ts.getLastRow()+1, 1,5,140).setValues(data); //you will need to define the size of the copied data see getRange()ination Sheet tab name
Any Idea on how I can combine the 2 scripts to mass apply a copied range from one sheet to a list of sheets ?
Thank you for responses :)
You should just create a function that is used to copy the data wanted from one sheet to another and then call this function when accessing the sheets in the for loop you are using.
Therefore, you can use something similar to this:
function copyFromOneSheetToAnother(var sourceSheet,
var destinationSheet) {
var range = sourceSheet.getRange('A1:EJ5');
var data = range.getValues();
destinationSheet.getRange(ts.getLastRow() + 1, 1, 5, 140).setValues(data);
}
The above function is expecting two parameters: the sourceSheet and the destinationSheet. As for calling this function, you can just use this:
function ChangesAug1() {
var data = SpreadsheetApp.openById('XXX').getSheetByName('ListOfSheetsToBeUpadated').getDataRange().getValues();
for (var row = 2; row < data.length; row++) {
var spreadsheet = SpreadsheetApp.openById(data[row][0]).getSheetByName('Template');
//get THE_DESTINATION_SHEET as well
copyFromOneSheetToAnother(spreadsheet, THE_DESTINATION_SHEET);
}
}
Reference
Sheet Class Apps Script;
Range Class Apps Script.
I am trying to come up with a function that could extract data from one workbook to another that has a separate format. I will refer to the workbooks as "Source" and "Destination". So, on the "Source", I have the data arranged in yearly tabs. However, on "Destination", I have tabs indicating the regions. I have attached snapshots of the two workbooks.
Since I have no basics in programming, I tried to come up with a code but it didn't quite work. The following is my attempt at a nested for-loop which first extracts the data from the "2015" tab of the first region ("Ampang"), and pastes it into the other workbook in the "Ampang" tab and the "2015" row. I ran the debugging function and it says that the "var data" is undefined.
function D() {
var ss = SpreadsheetApp.getActiveSpreadsheet();//open destination worksheet
var sss = ss.getSheets(); //get all destination sheets
//var sheetname = ss.getSheetName(); //get sheet names
var sheet1 = SpreadsheetApp.openByUrl("https://docs.google.com/spreadsheets/d/1jJ8QysQTmS5tG4wvNCxqdbWvAbdbmJm5uatdgIHe6tw/edit#gid=793399042"); //open where data is located
var sheet = sheet1.getSheets(); //get all the sheets required
for (j = 0; j<sss.length; j++) {
for (i = 0; i <sheet.length; i++) {
switch(sheet[i].getSheetName()) {
case "Main Menu" :
break;
default:
var data = sheet.getSheets()[i].getRange(i+1, i+2, 1, 2); //get the data for Specific Region and then Changing the Year
var destination = sss[j].getRange(j,j+1,1,2); //pasting the data to the specific year at the Specific Region Tab/
data.copyTo(destination);
}
}
}
}
[Update 1]
So, I realized that the copyTo() function doesn't work when the data are in separate workbooks so I have come up with a new code below:
function D() {
// define the source sheets
var ss = SpreadsheetApp.openByUrl("https://docs.google.com/spreadsheets/d/1jJ8QysQTmS5tG4wvNCxqdbWvAbdbmJm5uatdgIHe6tw/edit#gid=793399042");
// get all source sheets
var source = ss.getSheets();
// define the target sheets
var ts = SpreadsheetApp.getActiveSpreadsheet();
// get all target sheets
var target = ts.getSheets();
// set nested for-loop
for (j = 0; j < target.length; j++) {
for (i = 0; i < source.length; i++) {
if (source[i].getSheetName() !== "Main Menu") {
var rangeSource = source[i].getRange(i+1,i+1,1,2); // get the source range
var values = rangeSource[i].getValues(); // get the values from the set range
}
if (target[j].getSheetName() !== "Main Menu") {
var rangeTarget = target[j].getRange(j+1,j+1,1,2); //get the target range
rangeTarget.setValues(values[i]); // paste the values to the target range
}
}
}
}
However, the var rangeSource and values are currently undefined. I still am trying to find the source of the error.
Source Sheets Snapshot
Destination Sheets Snapshot
You've defined sheet as all the sheets
var sheet = sheet1.getSheets(); //get all the sheets required
So data needs to be
var data = sheet[i].getRange(i+1, i+2, 1, 2); //get the data for Specific Region and then Changing the Year
See is that helps.
Ok...not sure how to do this. Right now I 4 sheets and 4 scripts for each sheet producing 4 json feeds. What I am trying to experiment with is having one script that will produce 1 json that I can use in a web page and just call the type of class. They are all formatted the same with columns etc.
Here is the Google Script App code I have.
function doGet(e){
// Change Spread Sheet url
var ss = SpreadsheetApp.openByUrl("https://docs.google.com/spreadsheets/d/SpreadsheetID/edit#gid=0");
// Sheet Name, Change Sheet to whatever name you used to name your sheet
var sheet = ss.getSheetByName("Class Sheet 1");
return getClasses(sheet);
}
function getClasses(sheet){
var dataObj = {};
var dataArray = [];
// collecting data starting from 2nd Row , 1st column to last row and last column
var rows = sheet.getRange(2,1,sheet.getLastRow()-1, sheet.getLastColumn()).sort([{column: 1, ascending: true}, 1]).getValues();
for(var i = 0, l= rows.length; i<l ; i++){
var dataRow = rows[i];
var record = {};
record['Name'] = dataRow[0];
record['Note'] = dataRow[1];
record['Address'] = dataRow[2];
record['StreetAddress'] = dataRow[3];
record['City'] = dataRow[4];
record['State'] = dataRow[5];
record['ZipCode'] = dataRow[6];
record['ContactName'] = dataRow[7];
record['EMailAddress'] = dataRow[8];
record['CustomerServicePhone'] = dataRow[9];
dataArray.push(record);
}
dataObj = dataArray;
var result = JSON.stringify(dataObj);
return ContentService.createTextOutput(result).setMimeType(ContentService.MimeType.JSON);
}
Scratching my head on this a little bit....I'm sure its something simple and I am probably over thinking things, but any help would be appreciated.
Possible Solution:
The e object in your doGet(e) provides a way to send parameters to your script. You can access different sheets with different url parameters. You can then easily get the requested SheetName through e.parameter. Use
https://script.google.com/.../exec?sheet=ClassSheet1 //for ClassSheet1
https://script.google.com/.../exec?sheet=ClassSheet2 //for ClassSheet2
Code.gs:
function doGet(e){
var ss = SpreadsheetApp.openByUrl("https://docs.google.com/spreadsheets/d/SpreadsheetID/edit#gid=0");
var sheetName = e.parameter.sheet;
var sheet = ss.getSheetByName(sheetName);
return getClasses(sheet);
}
You can also provide UI in your web-app to select a sheet.
https://docs.google.com/spreadsheets/d/1wAxZROq-HqGSZIeBnOShiLP1x-maCpVhvfr6MKixVZE/edit#gid=1767460404
I am attempting to grab the data in a data range on a data sheet, then loop over that data, match the row values in Column C to the row values in a different (tracker) sheet also located in Column C, and for the matched data, copy the whole row in data sheet to the bottom of the data sheet.
All of this is supposed to be triggered when I enter "Open" in a set field in the status tracker.
What I have done so far (hopefully) is to locate the values to match in the data sheet but I am unsure as to how to use the .copyto function correctly now such that it copys the data to the end of the loop. My code so far: (without .copy.
function grabmyRequestID(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = SpreadsheetApp.getActiveSheet();
var range = sheet.getActiveCell();
var ss2 = ss.getSheetByName("Status Tracker")
var searchforrange = ss2.getRange("C:C")
var searchfor = searchforrange.getValues()
Logger.log("Request ID: " +searchfor)
return searchfor
}
function findDuplicates(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = SpreadsheetApp.getActiveSheet();
var range = sheet.getActiveCell();
var ss2 = ss.getSheetByName("Status Tracker")
var ss3= ss.getSheetByName("All Output")
var sheetNametoWatch = "Status Tracker"
var columntoWatch = 4
var valuetoWatch = "Open"
var searchfor = grabmyRequestID()
if (sheet.getName() == sheetNametoWatch && range.getColumn()
== columntoWatch && range.getValue() == valuetoWatch){
var data = ss3.getRange("C:C").getValues()
for (i=0; i<data.length; i++){
if (data[i] == searchfor && searchfor !=""){
Logger.log('found it')
}
}
}
}
As you can see, I am running two functions, grabmyRequestID, which grabs the id from the tracking sheet and findduplicates, which matches it with the ids from the data sheet.
I now just want it to copy the whole row where it found the matched column and copy that row to the end of the data sheet. I have tried a few ways but I never actually get any output. I am pretty new to this so I hope somebody can help me out.
I am also not sure entirely sure if my trigger works for this loop.
Any help would be appreciated.
I'm doing a data transfer of several spreadsheets to a single one, what I do is transfer the last data of certain columns to the master spreadsheet and also insert them in the last available row of certain columns, for now, I insert all the data but I would like to to know how I can have it examine the master spreadsheet so that if those data already exist, it does not delete them but update them. The script that I have is the following ...
function Gas10(){
var ss1 = SpreadsheetApp.openById("ID");
var ssh1 = ss1.getSheetByName("Sheet 1");
var lastRow1 = ssh1.getLastRow();
var gtRange1 = ssh1.getRange("C"+(lastRow1)+":K"+(lastRow1)).getValues();
var gtRange2= ssh1.getRange("A" + (lastRow1)).getValue();
var ss2 = SpreadsheetApp.getActiveSpreadsheet();
var ssh2 = ss.getSheetByName("Sheet 2");
var lastRow2 = ssh2.getLastRow() + 1;
var setRange1 = ssh2.getRange(lastRow2, 4, gtRange1.length, gtRange1[0].length).setValues(gtRange1);
var setRange2 = ssh2.getRange(lastRow2, 3).setValue(gtRange2);
}
I need to know how I can do it when I insert a piece of information (I already do that), but update it if it already exists. This is the example that I created so that it can be better understood, in this example I have two sheets of which from sheet 1 I pass data to sheet 2 and what I'm looking for is that sheet 2 updates all the data that are equal to (Name, Num, Proyect). I hope that now I understand better what I'm looking for.
Basically what you have to do is
get the new Line you want to add to the destination spreadsheet
get all the required datas of the destination spreadsheet
Check if the new Line datas have the same datas than in the destination data array
If so change ID value
paste changed datas in the destination spreadsheet
based on this spreadsheet The code should look something like this
function Gas10(){
var ss1 = SpreadsheetApp.getActiveSpreadsheet();
var ssh1 = ss1.getSheetByName("Sheet 1");
var ssh2 = ss1.getSheetByName("Sheet 2");
var lastRow1 = ssh1.getLastRow();
var lastCol1 = ssh1.getLastColumn();
var newLine = ssh1.getRange(lastRow1, 2, 1, lastCol1 - 1 ).getValues();
var destDatas = ssh2.getDataRange().getValues();
for (var i = 1; i < destDatas.length; i++)
{
if (newLine[0][0] == destDatas[i][0]
&& newLine[0][1] == destDatas[i][1]
&& newLine[0][2] == destDatas[i][2])
{
destDatas[i][3] = newLine[0][3];
}
}
// add newLine to destDatas
destDatas.splice(destDatas.length, 0, newLine[0]);
var lastColumn = ssh2.getLastColumn();
var lastRow2 = ssh2.getLastRow() + 1;
ssh2.getRange(1, 1, destDatas.length, lastColumn).setValues(destDatas);
ssh1.deleteRow(lastRow1);
}
Here's an example I played around with:
It looks at the slave sheet for any data. When it finds data it puts the row and col and value into an obj which is then added to an array. When it finishes it calls the updMaster which then looks for data in those same cells (assuming that the cells are in the same place if those cells are blank then it adds data and I also changed the background to lightblue to show me where it updated the cells.
You could run the getSlaveData() for different sheets if you wish.
function getSlaveData(){
var ss=SpreadsheetApp.getActive();
var ssh=ss.getSheetByName('Sheet2');
var sA=[];
var srg=ssh.getDataRange();
var svA=srg.getValues();
for(var i=0;i<svA.length;i++){
for(var j=0;j<svA[i].length;j++){
//if(svA[i][j]){
if(!ssh.getRange(i+1,j+1).isBlank()){//optional way to look for values
var sObj={};
sObj['row']=i + 1;
sObj['col']=j + 1;
sObj['value']=svA[i][j];
sA.push(sObj);
}
}
}
updMaster(sA);
}
function updMaster(sA){
var ss=SpreadsheetApp.getActive();
var msh=ss.getSheetByName('Sheet1');
for(var i=0;i<sA.length;i++){
if(msh.getRange(sA[i].row,sA[i].col).isBlank()){
msh.getRange(sA[i].row,sA[i].col).setValue(sA[i].value);
msh.getRange(sA[i].row,sA[i].col).setBackground('lightblue');
}
}
}