2011-10-21 77 views
38

Tôi có một Apps Script liên tục nhận được lỗi này. Đánh giá bằng email thông báo, có vẻ như thời hạn là 5 phút. Có ai biết nếu có một cách để kéo dài thời hạn này? Hoặc có lẽ có cách nào để gọi Apps Script một lần nữa và nó nhận từ nơi nó rời đi? Bất kỳ trợ giúp được đánh giá cao.Đã vượt quá thời gian thực thi tối đa trong Google Apps Script

+2

bạn có thể chia sẻ các tập lệnh bạn đang chạy? Bạn có thể điều chỉnh nó để làm cho nó nhanh hơn. – Eduardo

+2

Bạn có thể bẻ cong các quy tắc bằng cách sử dụng Dịch vụ HTML để khởi chạy các "lần lặp" riêng biệt của tập lệnh trên các tập hợp con của tác phẩm của bạn. [Bruce McPherson đã viết blog về nó.] (Http://ramblings.mcpher.com/Home/excelquirks/htmlservice/parallel) – Mogsdad

+1

Nếu bạn là khách hàng doanh nghiệp, giờ đây bạn có thể đăng ký [Quyền truy cập sớm vào Trình tạo ứng dụng] (https://developers.google.com/apps-script/guides/apps-script-eap), bao gồm [Hạn ngạch linh hoạt] (https://developers.google.com/apps-script/guides/services/quotas #flexible_quotas_early_access). – browly

Trả lời

56

Một điều bạn có thể làm (điều này tất nhiên phụ thuộc vào những gì bạn đang cố gắng để thực hiện) là:

  1. Store thông tin cần thiết (ví dụ như một bộ đếm vòng lặp) trong một bảng tính hoặc một cửa hàng vĩnh viễn (tức ScriptProperties).
  2. Yêu cầu tập lệnh của bạn chấm dứt sau mỗi năm phút.
  3. Thiết lập trình kích hoạt theo thời gian để chạy tập lệnh sau mỗi năm phút (hoặc tạo trình kích hoạt lập trình bằng cách sử dụng Script service).
  4. Trên mỗi lần chạy, hãy đọc dữ liệu đã lưu từ cửa hàng vĩnh viễn mà bạn đã sử dụng và tiếp tục chạy tập lệnh từ nơi nó đã dừng lại.

Đây không phải là giải pháp một kích thước phù hợp, nếu bạn đăng mã, mọi người sẽ có thể hỗ trợ bạn tốt hơn.

Đây là một mã số trích đoạn đơn giản từ một kịch bản mà tôi sử dụng mỗi ngày:

function runMe() { 
    var startTime= (new Date()).getTime(); 

    //do some work here 

    var scriptProperties = PropertiesService.getScriptProperties(); 
    var startRow= scriptProperties.getProperty('start_row'); 
    for(var ii = startRow; ii <= size; ii++) { 
    var currTime = (new Date()).getTime(); 
    if(currTime - startTime >= MAX_RUNNING_TIME) { 
     scriptProperties.setProperty("start_row", ii); 
     ScriptApp.newTrigger("runMe") 
       .timeBased() 
       .at(new Date(currTime+REASONABLE_TIME_TO_WAIT)) 
       .create(); 
     break; 
    } else { 
     doSomeWork(); 
    } 
    } 

    //do some more work here 

} 

Chú ý # 1: Biến REASONABLE_TIME_TO_WAIT nên phải đủ lớn để kích hoạt mới cháy. (Tôi đặt nó đến 5 phút nhưng tôi nghĩ nó có thể nhỏ hơn thế).

LƯU Ý # 2: doSomeWork() phải là một hàm thực thi tương đối nhanh (tôi có thể nói dưới 1 phút).

LƯU Ý # 3: Google đã không dùng nữa Script Properties và được giới thiệu Properties Service thay thế. Chức năng đã được sửa đổi cho phù hợp.

+1

Có giới hạn về tần suất kích hoạt có thể đi không? Tôi nghĩ rằng có thể có một giới hạn kích hoạt mỗi 24 giờ hoặc một cái gì đó ... Cảm ơn! – Kalin

+0

Tôi không nghĩ rằng điều này sẽ làm việc cho tiện ích. Add-on timed-trigger chỉ cho phép thực hiện mỗi giờ một lần. Bạn có biết bất kỳ giải pháp nào khác để giữ cho một tác vụ chạy và xử lý một lượng lớn dữ liệu từ bảng excel. – angelokh

+0

Điều này có tác dụng phụ của việc để lại tất cả các trình kích hoạt dựa trên thời gian cũ trong danh sách kích hoạt của dự án ... Không chắc chắn các trình kích hoạt thời gian đã hết hạn được cho là bị xóa. – staggart

21

Ngoài ra, hãy cố gắng giảm thiểu số lượng cuộc gọi đến các dịch vụ của google. Ví dụ: nếu bạn muốn thay đổi một dải ô trong bảng tính, không đọc từng ô, hãy thay đổi nó và lưu trữ lại. Thay vào đó hãy đọc toàn bộ phạm vi (sử dụng Range.getValues()) vào bộ nhớ, biến đổi và lưu trữ tất cả cùng một lúc (sử dụng Range.setValues()).

Điều này sẽ giúp bạn tiết kiệm rất nhiều thời gian thực hiện.

5

Tôi đã sử dụng ScriptDB để lưu vị trí của mình trong khi xử lý một lượng lớn thông tin trong một vòng lặp. Tập lệnh có thể/vượt quá giới hạn 5 phút. Bằng cách cập nhật ScriptDb trong mỗi lần chạy, kịch bản có thể đọc trạng thái từ db và chọn nơi nó đã dừng lại cho đến khi tất cả quá trình xử lý hoàn tất. Hãy thử chiến lược này và tôi nghĩ bạn sẽ hài lòng với kết quả.

+1

Có vấn đề tương tự với tập lệnh lặp qua 750 địa chỉ email trên bảng tính. Làm thế nào để bạn lưu trữ nơi mà các kịch bản còn lại và tiếp tục thực hiện? – jwesonga

+0

bạn có thể cung cấp thêm chi tiết ... mã mẫu nếu có thể..hoặc liên kết để biết thêm chi tiết. –

+0

ScriptDb không còn được dùng nữa. –

12

Anton Soradoi's answer có vẻ OK nhưng xem xét sử dụng Cache Service thay vì lưu trữ dữ liệu vào một trang tính tạm thời.

function getRssFeed() { 
    var cache = CacheService.getPublicCache(); 
    var cached = cache.get("rss-feed-contents"); 
    if (cached != null) { 
    return cached; 
    } 
    var result = UrlFetchApp.fetch("http://example.com/my-slow-rss-feed.xml"); // takes 20 seconds 
    var contents = result.getContentText(); 
    cache.put("rss-feed-contents", contents, 1500); // cache for 25 minutes 
    return contents; 
} 

Cũng lưu ý rằng tính đến tháng năm 2014 limitation of script runtimelà 6 phút.

+0

Điều này dường như là cách dễ nhất để giải quyết vấn đề, vì bạn không cần phải thiết lập cũng như không quan tâm đến bất kỳ tài nguyên nào khác (bảng tính, cơ sở dữ liệu, ...) và tất cả các mã script vẫn nằm trong chính kịch bản lệnh. Cảm ơn! – dubrox

+1

Bạn có thể cho ví dụ về chức năng tổng quát không? –

4

Nếu bạn đang sử dụng phiên bản G Suite Business hoặc Enterprise. Bạn có thể register early access for App Maker sau khi nhà sản xuất ứng dụng cho phép script chạy runtime của bạn sẽ tăng thời gian chạy từ phút 6-30 phút :)

Thông tin chi tiết về nhà sản xuất ứng dụng Click here

Các vấn đề liên quan