I have many buttons on my sheet, to hide and unhide some rows.
function hide1() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[2];
sheet.hideRows(24,11);
}
function unhide1() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[2];
sheet.showRows(24,11);
}
I have also created a script to duplicate this sheet, in order to create a new one to be filled.
function clonemastersheet() {
var sheetc = SpreadsheetApp.getActiveSpreadsheet()
var getname = sheetc.getRange("t10").getValue();
var name = getname
var pp = SpreadsheetApp.getActiveSpreadsheet();
var mastersheet = pp.getSheetByName('Form0').copyTo(pp);
mastersheet.setName(name)
pp.setActiveSheet(mastersheet)
PROBLEM:
When it duplicates the new sheet buttons dont work because the macros are related to the first one.
I need to create a script that will be duplicated with the sheet and work with them.
Is it possible?
function hide1() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
sheet.hideRows(24,11);
}
function unhide1() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
sheet.showRows(24,11);
}
Related
I have an Excel file with one sheet and one chart. I am trying to copy this chart and paste it on a new Word document using OpenXml SDK. I do not want an image of the chart, but an editable chart object, not referenced to the Excel file.
This is what I tried:
using (SpreadsheetDocument document = SpreadsheetDocument.Open("Test1.xlsx", true))
{
var bkPart = document.WorkbookPart;
var workbook = bkPart.Workbook;
var s = workbook.Sheets.FirstOrDefault();
var wsPart = bkPart.WorksheetParts.FirstOrDefault();
var dp = wsPart.DrawingsPart;
var dWs = dp.WorksheetDrawing;
var cp = dp.ChartParts.FirstOrDefault();
var plotArea = cp.ChartSpace.Descendants<PlotArea>().FirstOrDefault();
using (var docx = WordprocessingDocument.Open("Test1.docx", true))
{
docx.MainDocumentPart.Document.Body.RemoveAllChildren();
var cpw = docx.MainDocumentPart.AddPart(cp);
var p = new DocumentFormat.OpenXml.Wordprocessing.Paragraph();
var r = new Run();
var d = new Drawing();
var i = new Inline();
var g = new Graphic();
var gd = new GraphicData();
var c = new DocumentFormat.OpenXml.Drawing.Charts.Chart();
docx.MainDocumentPart.Document.Body.Append(p);
p.Append(r);
r.Append(d);
d.Append(i);
i.Append(g);
g.Append(gd);
gd.Append(c);
// I am stuck here
}
}
I tried to take the ChartPart from Excel and adding it to the Word document and then to create a new chart referencing the inserted new ChartPart. Unfortunately, I am stuck on this step. How can I get and use this reference to create the chart? Otherwise is there another way to copy a chart from Excel to Word?
Thanks in advance.
I found this workaround to copy a chart from Excel to Word:
Create a new ChartPart on the Word document.
Add to this ChartPart a ChartSpace cloned from Excel.
Add a new chart to the Word document referencing the new ChartPart.
This is the code:
using (SpreadsheetDocument document = SpreadsheetDocument.Open("Test1.xlsx", true))
{
var bkPart = document.WorkbookPart;
var workbook = bkPart.Workbook;
var s = workbook.Sheets.FirstOrDefault();
var wsPart = bkPart.WorksheetParts.FirstOrDefault();
var dp = wsPart.DrawingsPart;
var dWs = dp.WorksheetDrawing;
var cp = dp.ChartParts.FirstOrDefault();
using (var docx = WordprocessingDocument.Open("Test1.docx", true))
{
MainDocumentPart mainPart = docx.MainDocumentPart;
ChartPart chartPart = mainPart.AddNewPart<ChartPart>("rId777");
chartPart.ChartSpace = (ChartSpace)cp.ChartSpace.Clone();
var paragraph = new DocumentFormat.OpenXml.Wordprocessing.Paragraph() { RsidParagraphAddition = "00C75AEB", RsidRunAdditionDefault = "000F3EFF" };
Run run = new Run();
Drawing drawing = new Drawing();
Inline inline = new Inline();
inline.Append(new Extent() { Cx = 5274310L, Cy = 3076575L });
DocProperties docPros = new DocProperties() { Id = (UInt32Value)1U, Name = "Chart7" };
inline.Append(docPros);
Graphic g = new Graphic();
var graphicData = new GraphicData() { Uri = "http://schemas.openxmlformats.org/drawingml/2006/chart" };
var chartReference = new ChartReference() { Id = "rId777" };
graphicData.Append(chartReference);
g.Append(graphicData);
inline.Append(g);
drawing.Append(inline);
run.Append(drawing);
paragraph.Append(run);
mainPart.Document.Body.Append(paragraph);
}
}
I have a problem.
How to get the filename from the url?
enter image description here
I wouldn't normally do this since you haven't shown us what you've tried, but I'm feeling generous.
This function should work for you. (Note that you'll need to grant permissions for it to run.)
function getFileNames() {
var sheet = SpreadsheetApp.getActive().getSheetByName("Get_File_Name");
var links = sheet.getRange("A2:A").getValues();
var filenames = [];
for (var i = 0; i < links.length; i++) {
var url = links[i][0];
if (url != "") {
var filename = SpreadsheetApp.openByUrl(links[i][0]).getName();
filenames.push([filename]);
}
}
var startRow = 2; // print in row 2 since row 1 is the header row
var fileNameColumn = 2; // Column B = column 2
var destination = sheet.getRange(startRow, fileNameColumn, filenames.length, filenames[0].length);
destination.setValues(filenames);
}
Another way
function getFileNames() {
var driveApp = DriveApp;
// SET THE SHEET HERE
var sheet = SpreadsheetApp.getActive().getSheetByName("Sheet1");
//SET THE URL LINK COLUMN HERE : From row 2 since row 1 is the header row till last row
var links = sheet.getRange("P2:P").getValues();
var filenames = [];
for (var i = 0; i < links.length; i++) {
var fileId = getIdFromUrl(links[i][0]);
if (fileId != "" && fileId != null) {
var getfile = DriveApp.getFileById(fileId);
var filename = getfile.getName();
Logger.log(filename);
filenames.push([filename]);
} else {
filenames.push([""]);
}
}
// SET STARTING ROW TO PRINT: From row 2 since row 1 is the header row
var startRow = 2;
// SET WHICH COLUMN TO PRINT : Column A = column 1 / Column B = column 2
// MAKE SURE THE SHEET LAST COLUMN HEADER IS FILLED + 1 (next column)
var fileNameColumn = sheet.getLastColumn() + 1;
var destination = sheet.getRange(startRow, fileNameColumn, filenames.length, filenames[0].length);
destination.setValues(filenames);
}
function getIdFromUrl(url) { return url.match(/[-\w]{25,}/); }
You can create a custom function in spreadsheets like this.
function getSSName(name) {
var ss = SpreadsheetApp.openByUrl(url);
return ss.getName();
}
I just started using Google Sheets and I'm having trouble when setting a script.
I need a cell (let's say "AF4") to get the last modification date of another cell (let's say "X4").
Here's my script so far:
`function onEdit(e)
{
var sheet = SpreadsheetApp.getActiveSheet();
var editRange = sheet.getActiveRange();
var editRow = editRange.getRow();
var editCol = editRange.getColumn();
var range = sheet.getRange("X4");
var rangeRow = range.getRow();
var rangeCol = range.getColumn();
if (editRow = rangeRow && editCol = rangeCol)
{
sheet.getRange("AF4").setValue(new Date());
}
}`
When I try to save it, it says "invalid transfer on left side, line 1, "code" "
I'd really apprecite any help with that.
Thank you,
CURTY
The syntax for your condition seems to be wrong, that's why the error appears :)
if (editRow = rangeRow && editCol = rangeCol)
in case you want to check based on more conditions, the syntax must be
if (condition) {
block of code to be executed if the condition is true
if (condition) {
block of code to be executed if the condition is true
}
}`
I modified a bit of your code that you get an idea, of what needs to be done in order to achieve your goal, this script to get the last modification date of column X and post "new date" into AF4 (so whenever you edit something on column "x" and the row 4 the date will be set in AF4)
function onEdit() {
var sheet = SpreadsheetApp.getActiveSheet();
var editRange = sheet.getActiveRange();
var editRow = editRange.getRow();
var editCol = editRange.getColumn();
var editCell = sheet.getActiveCell();
var range = sheet.getRange("X4");
var rangeRow = range.getRow();
var rangeCol = range.getColumn();
if( sheet.getName() == "Sheet1" ) { //checks that we're on the correct sheet
if( editCell.getColumn() == 24 ) { //checks that we're on the correct column ; column x = 24
if( editCell.getRow() == 4 ) { //checks that we're on the correct row ; row 4 = 4
sheet.getRange("AF4").setValue(new Date());
SpreadsheetApp.getActive().toast('Data changed', 'Info', 2); //give a Info, that something was done correctly
}
}
}
}
Hope this will help you!
EDIT
Script from comments request, whenever something on Column X is changed, add Date to column AF in the same row
function onEdit() {
var sheet = SpreadsheetApp.getActiveSheet();
var editRange = sheet.getActiveRange();
var editCol = editRange.getColumn();
var editCell = sheet.getActiveCell();
var range = sheet.getRange("X4");
if( editCell.getColumn() == 24 ) {
var rangeCol = range.getColumn();
var editRow = editRange.getRow();
sheet.getRange(editRow,rangeCol+8).setValue(new Date()); //use the RangeCol + 8 Columns
SpreadsheetApp.getActive().toast('Date added', 'Info', 2); //this line can be deleted
}
}
So I have some code to create calendar events based on a jobs sheet for meetings but I can't seem to get it working as I would expect- I have columns 24 and 25 to keep track of if its been put in the calendar and the calendar event id, I don't want it to delete then create a new event for ones that have already been added (as this spreadsheet can get large) so thats why I keep track via on edit. But is seems to create a new event every time. If anyone can have a look over that would be great as I've been struggling for the past 3 days with this.
Many thanks
//push new events to calendar;
function pushToCalendar() {
//spreadsheet variables
var sheet = SpreadsheetApp.getActiveSheet();
var lastRow = sheet.getLastRow();
var range = sheet.getRange(2,1,lastRow,26);
var values = range.getValues();
var updateRange = sheet.getRange('Z1');
//calendar variables
var calendar = CalendarApp.getCalendarById('insert calendar code here')
//show updating message
updateRange.setFontColor('red');
var numValues = 0;
for (var i = 0; i < values.length; i++) {
//check to see if name are filled out
if ((values[i][0].length > 0) && (values[i][1].length > 0)) {
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// if it has been edited delete old event
if (values[i][23] ='n') {
try{
var eventIdCell =values[i][24];
var eventId =calendar.getEventSeriesById(eventIdCell);
eventId.deleteEventSeries();
}
catch (e) {
// do nothing - we just want to delete if it has been edited and the old event if it still exists
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//check if it's been entered before
if (values[i][23] !='y') {
var newEventTitle = values[i][0] + ' - ' + values[i][1]+' - ' + 'Sample';
var newEvent = calendar.createAllDayEvent(newEventTitle, new Date(values[i][6]));
//get ID
var newEventId = newEvent.getId();
//mark as entered, enter ID
sheet.getRange(i+2,24).setValue('y');
sheet.getRange(i+2,25).setValue(newEventId);
}
}
numValues++;
}
//hide updating message
updateRange.setFontColor('white');
}
//////////////////////////////////////////////////////////////////////////////////////////////////////
//add a menu when the spreadsheet is opened
function onOpen() {
var sheet = SpreadsheetApp.getActiveSpreadsheet();
var menuEntries = [];
menuEntries.push({name: "Update Calendar", functionName: "pushToCalendar"});
sheet.addMenu("Jobs Calendar", menuEntries);
}
//////////////////////////////////////////////////////////////////////////////////////////////////////
function onEdit(event){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var actSht = event.source.getActiveSheet();
var actRng = event.source.getActiveRange();
var activeCell = actSht.getActiveCell();
var row = activeCell.getRow();
if(row < 2){
return; //If header row then return
}
else{
var index = actRng.getRowIndex();
var updateCalCell = actSht.getRange(index,24);
var eventIdCell = actSht.getRange(index,25);
change updated on colander status to n
updateCalCell.setValue('n');
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////
You made a simple error in the condition : the EQUAL operator in comparison is == and not =, change that and it will work.
if (values[i][23] =='n') {
I am trying to set a formula in Google Spreadsheet F2:F if E2:E has a date. If E2:E is blank, then no formula is set to F2:F.
My Code so far. Any Help or suggestions would be much appreciated.
function formula(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[0];
var date = Utilities.formatDate(new Date(), "America/New_York", "MMMM dd, yyyy");
var colE = sheet.getRange("E2:E");
var colF = sheet.getRange("F2:F");
if (colE != date){
colF.setFormula("=round(abs(E2:E-NOW()),-1)");
} else {
colF.setValue("");
}
}
Here is how to do it...
function formula(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[0];
var colE = sheet.getRange("E2:E").getValues();
var colF = sheet.getRange("F2:F").getFormulas();
for(var n in colE){
if (typeof(colE[n][0])=='object'){
colF[n][0] = "=round(abs(E"+n+":E-NOW()),-1)";
} else {
colF[n][0] = "";
}
}
sheet.getRange('F2:F').setFormulas(colF);
}