Google Sheet Auto Import XLS with Dynamic Filename - google-apps-script

I am trying to find an app script solution to automatically import an Excel file into my Google Sheet each morning. I have found a number of examples on this forum as to how to import an Excel file however I have two challenges that I have not been able find a solution for:
The filename of the Excel sheet I need to import changes daily as it is an inventory report from the night prior and the filename is based on the date and time the report was run.
Only the first 10 of the 14 characters of the filename are predictable. The filename is always "IV" followed by the year, month, day and the time the report ran however the time that the report runs is not consistent. For example IV201907142308.xls means the report ran July 14, 2019 at 11:08pm however the night before the report ran at 11:04pm.
Possible workaround:
Instead of trying to import an Excel file from a specified folder by matching only part of the filename I could have another sheet that runs a script listing all files in a folder and the link to each file and have the import Excel file script refer to that list in order to find the link to the correct Excel file. I can create the list all files script but I am not sure how to have the import Excel file script refer to a link on the sheet in order to upload the correct Excel file.
How do I solve the problem?

Actually, you don't even need your file's name to import it. Since you mention the time can change and doesn't matter, I'm assuming only one file is generated per day.
If it's indeed the case, you can find it by it 'created date' by comparing it to yesterday's date.
function importYesterdayReport() {
var folders = DriveApp.getFoldersByName(/* your folder's name */);
var files = folders.next().getFiles();
//yesterday's date setup
var date = new Date();
date.setDate(date.getDate() - 1)
var yesterday = date.toDateString(); //because time won't be the same
//loop thru files to find yesterday's
while(files.hasNext()){
var file = files.next();
date = file.getDateCreated();
var fileDate = date.toDateString(); //because time won't be the same
if(fileDate === yesterday){
/* your import code */
}
}
}
getDateCreated() method
Date() JS ref
Other option id to search for your file title. Since the search criteria is 'contains' the fact that the hours change is not significant.
So you can replace the 'yesterday's date setup by :
var date = new Date();
var year = date.getFullYear();
var month = ("0"+(date.getMonth()+1)).slice(-2);
var day = date.getUTCDate();
and use this instead for var files : (will need to be after yesterday's date setup)
var searchCrit = 'title contains "IV'+year+month+day+'"'
var files = folders.next().searchFiles(searchCrit);
searchFiles() method

Related

Possible to rename multiple .csv in drive by content(s) of that file?

I got hundreds of datachunks (adding up daily) within a single gDrive Folder.
They all nare amed pretty similat like in_history.csv, in_history (1).csv, in_history (2).csv, out_history.csv, out_history (2).csv, ...
...
The all follow the exact same format, where colum three holds a date/time stamp:
Currency
Amount
Date (UTC)
USD
1000
2022-07-30 17:21:18
EUR
455
2022-04-13 18:04:06
...
I kindly ask someone to point me into a direction on how to rename each file based on "column" 3 (Date) so I end with filenames like
IN - 2022/04/13 - 2022/07/30.csv
IN - yyyy/mm/dd - yyyy/mm/dd.csv
OUT - yyyy/mm/dd - yyyy/mm/dd.csv
...
In a programmatical way I think I need something like this:
Loop through a defined folder to get all filenames
Loop through each containing .csv to get the lowest and highest date within colum 3
If filename contains "in" change filename to "IN - - .csv
I want to start using AppScript as I already found out how to trigger tasks on intervals and hope to learn more to utilize AppScript to ease up my daily life.
I lack o funderstanding on how to loop through the folder and get all files, from those files the rangse of "column" 3 (while there are no columns in .csv), extract the the smallest to highest date and modify the corresponding filename. Its a myth - not even sure if possible at all.
Any pointers or maybe even a starter I can wrap my brain around?
Note: The gDRive I am working in is a "personal" (not part of google organizational accounts/drives).
I've coded up something quickly without much error handling, it should give you the result based on your given data files,
The high-level idea is,
Get the files from the src folder.
Read each file's content, and extract the last column dates.
Sort the dates, then take the last item in the list as StartDate and the first item in the list as EndDate.
Create the new file name as {IN or OUT} - {StartDate} - {EndDate}.csv.
Rename the old file to the above file name.
function fileRenamingTask() {
var srcFolderId = "Your src folder id";
var destFolderId = "Your dest folder id, can be the same as src folder";
var SourceFolder = DriveApp.getFolderById(srcFolderId)
var Files = SourceFolder.getFiles();
while(Files.hasNext()) {
var file = Files.next();
var newFileName = getNewFileName(file);
rename(file, newFileName, destFolderId)
}
}
function getNewFileName(file) {
var rows = parseCsv(file);
var dates = []
for (i = 1; i < rows.length; i++) {
var dateTime = rows[i][2]; //assuming that the date item is always at the 3rd place
var dateStr = dateTime.split(" ")[0]; //split with the space and get the date part
dates.push(dateStr);
}
//sort the dates from latest to oldest
dates.sort( function(a, b) {
return new Date(b) - new Date(a);
}
)
var startDate = dates[dates.length - 1];
var endDate = dates[0];
var dateRange = `${startDate.replace(/-/g, '/')} - ${endDate.replace(/-/g, '/')}`;
var fileName = file.getName().split('_')[0].toUpperCase(); //get the first part of the filename in_history
return `${fileName} - ${dateRange}.csv`;
}
function parseCsv(file) {
var data = file.getBlob().getDataAsString();
var lines = data.split("\n");
var data = lines.map(function(lin){return lin.split(",")});
return data;
}
function rename(file, newFileName, folderId) {
var FileRename = file.makeCopy(newFileName);
var DestinationFolder = DriveApp.getFolderById(folderId)
DestinationFolder.addFile(FileRename);
}

Is there a way to upload data from google sheets into calendar with concatenate data?

I am very new to using google script and is something I have taken interest in recently, with no prior knowledge I have so far been trying to self teach.
I have been playing around with a excel formula that will grab some data from a table on a daily basis and concatenate into a Date and Time format.
So I have the following data in a table:
Event : Time Start : Time End : Location : Description
Work Rota: 24/01/2022 08:30:00 : 24/01/2022 19:30:00 : (postcode) : Work Shift for today
The first row being headers and the 2nd row with the data I am trying to utilise.
The data in the Time Start and Time End column is data using the concatenate formula from another spreadsheet.
If this was not a concatenate formula, the correct Date and Time format for the script works fine, However I understand due to the concatenate formula, the data for the string format is not suitable for the createEvent function.
I have been playing around with google script to find a way to take this data and being able to import it into my google calendar and after struggling now for multiply days! I cannot find a resolution.
Is there a formula or process, that can read the data in column 2 and 3 to convert the data into a suitable format needed for the createevent function
This is the script I have been using.
function addEvents() {
var ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("TEST");
var lr = ss.getLastRow();
var cal = CalendarApp.getCalendarById("calendarId");
var data = ss.getRange("A2:E" + lr).getValues();
for (var i = 0;i<data.length;i++){
cal.createEvent(data[i][0], data[i][1], data[i][2], {location: data[i][3], description: data[i][4]});
}
}
I appreciate anyone that may be able to help with this and thank you in advance!
I would have tried:
cal.createEvent(data[i][0], new Date(data[i][1]), new Date(data[i][2]), {location: data[i][3], description: data[i][4]});
}

Google Scripts Format Date Creates Impossible Date

In a very stripped down sense, this is my issue. I am creating a script that will look for a folder with a given name inside a particular folder. If the script finds a folder with that name, it will move the current document to that folder. If not, it should create a folder with that name, and then move the document.
The current naming convention on folders is "Billed 6/18", as an example.
Right now my script is throwing the date out in a weird way, and that won't help me with my later search by file name in a string format.
function MoveTicket() {
var ss = SpreadsheetApp.getActive()
var billfold = DriveApp.getFolderById(id)
var currentdate = Utilities.formatDate(new Date(), "GMT-4", "M/D")
var billfoldname = ('Billed ' + currentdate)
Logger.log(billfoldname)
}
But my log shows [20-06-18 15:41:59:480 EDT] Billed 6/170
I've attempted changing the timezone from GMT-4 to UTC, or changing the date format to M/DD or MM/DD, and I still see the same issue. Just logging new Date() does show the correct date.
Where is it getting 170 for the date? How can I correct it?
Solved. Was using D which gave day of the year instead of d which gave day of the month.
var currentdate = Utilities.formatDate(new Date(), "GMT-4", "M/d")
Simple Date Format

How to open a spreadsheet only by name of the corresponding file in Google Sheets?

I need a way to open a spreadsheet only by having the name of the corresponding file and the folder where the file is located. What I'm trying to do is creating a temporary copy of an active spreadsheet and reading information from the copy file rather than the active one. But unfortunately this copy file won't have a constant ID and URL as it's going to be erased every time after the script is done, and re-created with the next running of the script.
What I already tried is using the URL of the temporary file in order to open the spreadsheet itself, as you can see below.
But it's not useful for me, as I don't have a constant URL of this file (as it will be erased in the end of the script and have a new URL with the next script). But I have a constant name of the file, as well as this will be the only file in the respective folder.
What I also tried is looking for methods to open file only using its name (which is "temp_copy" in a 'temp_folder'). But I didn't find a working solution.
var report = SpreadsheetApp.getActiveSpreadsheet();
var temp_folder =
DriveApp.getFolderById("1EAsvVcFjIw5iGTeF_SxxQJLVlaLHl_pR");
DriveApp.getFileById(report.getId()).makeCopy("temp_copy", temp_folder);
var temp_copy = SpreadsheetApp.openByUrl(' ');
var hiddenSheet = temp_copy.getSheetByName('DATE');
var lastRow = hiddenSheet.getSheetValues(1,1,1,1);
var sheet = temp_copy.getSheetByName('forCSV');
var lastColumn = sheet.getLastColumn();
var activeRange = sheet.getRange(1,2,lastRow,lastColumn);
What I'm expecting as a result is to make the link between the 3rd line of the code (when making a copy of the basic file) and 5th line of the code onwards (when referencing specific range from the temporary file) only by using name of the file or respective folder. In theory it seems so easy, I should be missing something somewhere...
Many thanks in advance!
You can use DriveApp to get a FileIterator which contains the Sheet.
var file, files = DriveApp.getFilesByName("temp_copy");
if (files.hasNext ()){
file = files.next(); // Get first result for name
} else {
return "";
}
var sheet = SpreadsheetApp.openById(file.getId())

using a variable in searchFiles Google script

I have a third party program that pulls daily data into CSV files with the filename starting with the date it ran e.g. 17072017filename.csv
I need a seperate spreadsheet that will take a date input from the user, which will then search through the files in drive until it matches the date on the CSV file. Once i find the file i want i can then use getFileID() and getRange() to copy various values from that CSV file.
This is what i have at the moment (where cell A2 in the spreadsheet is where the user can type the date they want e.g. 17072017).
Issue seems to be that i can't pass the date (which will change everyday) as a variable in searchFiles(). Is this even possible?
This is what i have so far
function myfunction()
{
var inputDate = SpreadsheetApp.getActiveSheet().getRange("A2").getValue();
var files = DriveApp.searchFiles('title contains 'inputDate'');
while (files.hasNext())
{
var file = files.next();
Logger.log(file.getName());
}
}
How about a following modification?
From :
var files = DriveApp.searchFiles('title contains 'inputDate'');
To :
var files = DriveApp.searchFiles("title contains '" + inputDate + "'");
If I misunderstand your question, I'm sorry.