среда, 2 апреля 2014 г.

Скрипт для сбора файлов по ссылкам из таблицы

Уже второй год накануне лицейской научно-практической конференции школьников я мучаюсь вопросом, как лучше организовать онлайн-регистрацию на конференцию и отправку тезисов. Пробовала разные решения, которые описывала раньше здесь и здесь.Однако ни одно решение не устраивало полностью. Поэтому в этот раз мы решили сделать все через стандартную форму Google, в которой в качестве обязательного поля требовалось вписать ссылку на файл с тезисами. Кроме того, приложили подробную инструкцию, как этот файл загрузить на Google диск и расшарить.
Как показала практика, большинство учеников с этой задачей справились без проблем. И вот, теперь возникла задача: есть здоровенная таблица, в которой куча ссылок как на документы Google, так и на документы Word, сохраненные на Google Drive. Очень хочется эти документы собрать в одном месте, и очень не хочется делать это вручную.
В итоге, появился небольшой скрипт, который это делает.

Как работает скрипт

Для того, чтобы скрипт скопировал все файлы из таблицы по ссылкам в одну папку, необходимо, что в таблице был столбец с заголовком "ID". Чтобы получить ID документа из ссылки на документ, использовала следующий метод: пусть в столбце B хранится URL, а в столбец C я хочу получить ID. Тогда в С2 я записываю формулу:
=left(right(B2;len(B2)-find("/d/";B2)-2);len(right(B2;len(B2)-find("/d/";B2)-2))-17)
Не уверена, что формулы выглядят одинаково для всех типов файлов, но для документов Google и Word - это так. Таким образом, в столбце ID имеем идентификаторы каждого документа. 
Вообще говоря, вот тут описан способ как программно получить ID по URL, однако он не работает для файлов Word, загруженных на Google Drive без преобразования.
Теперь создаем новый скрипт и копируем туда код (в примере код уже размещен и на панели добавлено меню "Copy files")
function copyFiles() {
var folder = DriveApp.createFolder('NewFolder');
folder.setSharing(DriveApp.Access.ANYONE, DriveApp.Permission.EDIT);
var sheet = SpreadsheetApp.getActiveSheet();
var rows = sheet.getDataRange();
var numRows = rows.getNumRows();
var numCols = rows.getNumColumns();
var titleRange = SpreadsheetApp.getActiveSheet().getRange(1, 1, 1, numCols);
var titles = titleRange.getValues();
var idCol = -1;
for (var i = 0; i <= numCols-1; i++) {
if (titles[0][i] === 'ID') {
idCol = i;
}
}
if(idCol>=0){
/**
Should be column "ID" in active sheet
To get ID(in the cell C2) from URL(in the cell B2) use this formula: C2 =left(right(B2;len(B2)-find("/d/";B2)-2); len(right(B2;len(B2)-find("/d/";B2)-2))-17)
*/
var range = SpreadsheetApp.getActiveSheet().getRange(2, idCol+1,numRows-1, 1);
var values = range.getValues();
for (var i = 0; i <= numRows - 2; i++) {
var currentId = values[i];
Logger.log(currentId);
var doc = null;
try {
doc = null;
var file = DriveApp.getFileById(currentId);
file.makeCopy(folder).setSharing(DriveApp.Access.ANYONE_WITH_LINK, DriveApp.Permission.VIEW);
}
catch (e) {
var file = null;
}
}
}
};
function onOpen() {
var sheet = SpreadsheetApp.getActiveSpreadsheet();
var entries = [{
name : "Copy all files to the NewFolder",
functionName : "copyFiles"
}];
sheet.addMenu("Copy files", entries);
};
view raw CopyFilesByURL hosted with ❤ by GitHub
В зависимости от того, сколько строк в таблице, скрипт может работать довольно долго. По окончании, на вашем диске Google появится папка NewFolder, в которую собраны все файлы. Дальше с ними можно делать то, что пожелаете.
Возможно, мы доблестно изобрели очередной велосипед, но, надеюсь, что этот способ кому-то облегчит жизнь.

Комментариев нет:

Отправить комментарий