Я построил скрипт, который извлекает из нескольких электронных таблиц и вычисляет общие значения. В основном, что происходит, несколько сотрудников будут вводить часы, выполненные по конкретной задаче для конкретного клиента. Затем я хочу рассчитать, сколько работы было сделано для конкретного клиента на главной электронной таблице и вывести некоторые аналитики.Google Script - превышено максимальное время выполнения
Итак, на главной электронной таблице есть вкладка для каждого клиента. Эта функция принимает имена листов из главной электронной таблицы и создает массив всех имен клиентов. Причина, почему я делаю это, заключается в том, что если новая вкладка будет создана, это имя клиента будет автоматически включено в массив клиентов.
function getCurrentCustomers() {
var sheets = servicesSpreadsheet.getSheets();
for (var i=0 ; i < sheets.length ; i++) {
if (sheets[i].getName() != "Services" && sheets[i].getName() != "Employee Files") {
currentCustomers.push(sheets[i].getName());
};
};
};
Следующая функция принимает взглянуть на все файлы в определенной папке Google Drive и возвращает идентификаторы в массиве. Это позволяет мне создать копию таблицы сотрудников, хранящейся в этой конкретной папке, и что значения электронной таблицы будут автоматически вычисляться по мере их изменения.
function listFilesInFolder() {
var folder = DriveApp.getFolderById("0B7zrWIHovJrKVXlsaGx0d2NFT2c");
var contents = folder.getFiles();
var cnt = 0;
var file;
while (contents.hasNext()) {
//Finds the file in the specified folder
var file = contents.next();
//Increases the count
cnt++;
//Gets the Id of the file
data = [
file.getName(),
file.getId()
];
//Appends it to the employeeId list
employeeIds.push(data);
};
return employeeIds;
};
Последняя функция - это то, что замедляет ее.
Сначала я создаю массив для всех возможных сервисов. К сожалению, есть отдельные услуги.
Затем я просматриваю всех клиентов. Для каждого клиента я просматриваю каждую службу, чтобы увидеть, отображается ли она на любой из таблиц сотрудников. Я думаю, что есть более эффективный способ сделать это. Сценарий Google истекает, прежде чем я даже пройду через одного полного клиента. Кроме того, я еще не включил электронные таблицы для всех сотрудников. Я просто тестирую фиктивные данные.
function calculateNumbers(){
var allServices = servicesSpreadsheet.getSheetByName("Services").getRange("Z2:Z137").getValues();
Logger.log(allServices);
Logger.log(allServices[0][0]);
employeeList = listFilesInFolder();
//Gets services spreadsheet range
/*Loops through all of the current customers (currentCustomers comes from function getCurrentCustomers)*/
for (var c = 0; c < currentCustomers.length; c++) {
var currentCustomer = currentCustomers[c];
var lastColumn = servicesSpreadsheet.getSheetByName(currentCustomer).getLastColumn();
var servicesRange = SpreadsheetApp.openById("1X3RRR3UVeot-DYCyXOsfVo0DoKjHezltwBPwUm8ZYig").getSheetByName(currentCustomer).getRange("A4:BC227").getValues();
//Loops through all of the services
var serviceTotal = 0;
for (var service = 0; service < allServices.length; service++){
//Loops through employee spreadsheet Ids
for (var i = 0; i < employeeList.length; i++) {
//Get employee spreadsheet ID
var spreadsheetId = employeeList[i][1];
//Open the employee spreadsheet by ID
var employeeSpreadsheet = SpreadsheetApp.openById(spreadsheetId);
//Get the sheets from the particular employee spreadsheet
var sheets = employeeSpreadsheet.getSheets();
//Gets the name of each sheet in the employee spreadsheet
var sheetsName = [];
for (var j = 0; j < sheets.length; j++) {
sheetsName.push(sheets[j].getName());
};
//Loops through all of the sheets in an employee spreadsheet ignoring the Services spreadsheet
for (var q = 0; q < sheetsName.length; q++) {
if (sheetsName[q] != "Services") {
//Gets the range of the spreadsheet
var range = employeeSpreadsheet.getSheetByName(sheetsName[q]).getRange("A5:E1000").getValues();
//Loops through the range to see if range matches service and customer
for (var r = 0; r < range.length; r++) {
if (range[r][3] == allServices[service][0] && range[r][1] == currentCustomer) {
serviceTotal += range[r][4];
};
};
};
};
};
//Adds the service total to the correct customer's spreadsheet
for (var serviceServices = 4; serviceServices <= servicesRange.length; serviceServices++){
var end = 0;
if (end > 0) {break}
else if (allServices[service][0] == servicesSpreadsheet.getSheetByName(currentCustomer).getRange(serviceServices,1).getValues()) {
servicesSpreadsheet.getSheetByName(currentCustomer).getRange(serviceServices,6).setValue(serviceTotal);
end += 1;
};
};
};
};
};
Первое изображение показывает, что работник таблицы выглядит. Второй показывает, как выглядит отдельный лист клиента. В основной таблице есть много листов клиента.
Одна из вещей, которые вы заметите, заключается в том, что у каждой службы есть категория. Я думал, может быть, проверить категорию, а затем проверить конкретную услугу. Есть 23 категории.
Я также надеялся, что существует возможность взглянуть только на службы, которые на самом деле работали над ними. Если никто никогда не выполнял настройку кампании, возможно, это можно было бы игнорировать.
Любая помощь была бы принята с благодарностью. Прошу прощения за длинный пост!
Wow! Это потрясающе. Я не могу поблагодарить вас за то, что вы нашли время ответить на все эти вопросы. Я сделаю изменения и посмотрю, что такое время выполнения. (Очевидно) Я очень новичок в кодировании. Это самая сложная вещь, которую я создал, и она получилась невероятно неэффективно, но вы помогли мне понять, почему. Если бы я мог купить вам выпить, я бы через секунду. Спасибо @DouglasGaskell! Честно говоря, это было так долго, я больше не ожидал, что никто не ответит, но подумал, что я сделаю это. – tonestrike