英文:
Using Google Apps Script to detect a calendar event with a keyword to copy and rename a template file to the appropriate year and month subfolder
问题
抱歉,由于涉及到代码部分的技术性内容,我无法提供翻译。
英文:
In my various groups of friends, I tend to be the one that everyone looks to in order to organize and plan everything. Love doing it, but it definitely helps when I have some sort of document to work off of.
In the dummy example I have to share, I am planning a potluck with some friends. I want to create a calendar event for it, and when I enter #potluck
in the event description, I want to be able to have the script take action by copying a template file I have specified, check the date of the event, and make the appropriate year and month folder (if they don't already exist), and copy the template file to that folder. Lastly, it renames the file to be "Potluck + event date" and replaces the #potluck
from the event description to be a URL to the event's newly created template file.
Hopefully I phrased all of that clearly...
Everything functions fine up until a certain point.
// Confirms whether the event has the #potluck tag
let description = event.getDescription();
if (description.search('#potluck') == -1) continue;
const eventDate = Utilities.formatDate(event.getStartTime(), "GMT", "MM-dd-yyyy");
// Get the year from the event date
const year = eventDate.split("-")[2];
// Get the month number from the event date
const monthNum = eventDate.split("-")[0];
// Get the month name from the month number
const monthNames = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
const month = monthNames[parseInt(monthNum, 10) - 1];
The first section will check Google Calendar for any events with the event description #potluck
and parses the date so it can create a year folder and month subfolder if they do not already exist.
// Get the root folder
var rootFolder = DriveApp.getFolderById("1jdLNv-vG6RfijAHZaIvQdfSEwBEq-UIB");
// Check if the year folder exists
var yearFolder = rootFolder.getFoldersByName(year);
if (yearFolder.hasNext()) {
yearFolder = yearFolder.next();
} else {
// Create the year folder
yearFolder = rootFolder.createFolder(year);
}
// Check if the month folder exists
var monthFolder = yearFolder.getFoldersByName(month);
if (monthFolder.hasNext()) {
monthFolder = monthFolder.next();
} else {
// Create the month folder
monthFolder = yearFolder.createFolder(month);
}
Where I seem to hit a snag is at line 72 when I have copied the file, renamed it, and created the year and month folders if they don't already exist. The script attempts to move the newly created file
var templateSheetId = "14IZEMR-fjgc8YvlgQJJCpyGotBJ3YqLTP87s38vWPaM";
var templateSheet = SpreadsheetApp.openById(templateSheetId);
var newSheet = templateSheet.copy("Potluck " + eventDate);
newSheet.moveTo(monthFolder);
For some reason, even though I believe I have followed the syntax of the documentation around moveTo()
, I am getting an error that reads:
> TypeError: newSheet.moveTo is not a function
Is there a different way I should be calling for this file to be moved? Is there a better way to relocate a file in Google Drive? As of now, it just creates it in my root Google Drive folder, but I cannot move it to monthFolder
after that.
I tried using moveTo()
to get the newly created file to move to the appropriate folder. When that did not work, I tried copying it there with copy()
and copyTo()
but both ran into a similar error. I looked at other functions like move()
but they result in the same issue. I tried following some tutorials where they move a file and remove the original, but that creates an entirely different function for one simple step (or so I believe it to be).
UPDATE:
Thanks to Daniel for informing me of the differences between creating an object with SpreadsheetApp
and DriveApp
My code was updated as follows:
var templateSheet = DriveApp.getFileById("14IZEMR-fjgc8YvlgQJJCpyGotBJ3YqLTP87s38vWPaM");
var newSheet = templateSheet.makeCopy("Potluck " + eventDate, monthFolder);
答案1
得分: 0
如评论中所述,这是因为newSheet
是一个Spreadsheet
对象。如果您查看文档,您可以找到其方法列表。Spreadsheet
方法用于操作电子表格数据,但它们不负责在Google Drive内移动文件。为此,您需要使用DriveApp
创建一个File
对象。以下是使用您的代码的示例:
var templateSheetId = "<ID>";
var templateSheet = SpreadsheetApp.openById(templateSheetId);
var newSheet = templateSheet.copy("Potluck " + eventDate);
var drivefile = DriveApp.getFileById(newSheet.getId())
drivefile.moveTo(monthFolder)
但我认为最好的方法是使用makeCopy()
来进行复制,它允许您立即设置名称和位置。如果您不需要操作电子表格,可以避免不必要地调用SpreadsheetApp
,这通常是一个良好的做法:
var templateSheetId = "<ID>"
var copy = DriveApp.getFileById(templateSheetId)
copy.makeCopy("Potluck " + eventDate, monthFolder)
总之,问题在于您在错误的类别中使用了某些方法。我建议您熟悉文档,以查看哪些方法属于哪些类别以及它们返回什么:
英文:
As mentioned in the comments, this is because newSheet
is a Spreadsheet
object. If you check the documentation you can find a list of its methods. The Spreadsheet methods manipulate the spreadsheet data, but they are not in charge of moving the file within Drive. For this you need to create a File
object with DriveApp
. Example with your code:
var templateSheetId = "<ID>";
var templateSheet = SpreadsheetApp.openById(templateSheetId);
var newSheet = templateSheet.copy("Potluck " + eventDate);
var drivefile = DriveApp.getFileById(newSheet.getId())
drivefile.moveTo(monthFolder)
But I think the best way is to make the copy with makeCopy()
, which allows you to set the name and location right away. If you don't need to manipulate the spreadsheet you can just avoid calling SpreadsheetApp
unnecessarily, which is generally a good practice:
var templateSheetId = "<ID>"
var copy = DriveApp.getFileById(templateSheetId)
copy.makeCopy("Potluck " + eventDate, monthFolder)
In conclusion, the problem was that you were using some methods with the wrong classes. I recommend you get acquainted with the documentation to see which methods belong to which classes, and what they return:
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论