【问题标题】:IMPORTXML into a Google Apps Script with Automatic Update将 IMPORTXML 导入具有自动更新功能的 Google Apps 脚本
【发布时间】:2017-08-26 00:17:33
【问题描述】:

我正在尝试让 Google 表格应用程序脚本适用于我正在使用的 IMPORTXML。

A1
=importxml("http://www.nfl.com/liveupdate/scorestrip/ss.xml","//@q")

A2
=importxml("http://www.nfl.com/liveupdate/scorestrip/ss.xml","//@h")

数据来自A1:B16

根据我在网上找到的一个脚本让它自动刷新:

function getData() {
  var queryString = Math.random();

  var cellFunction1 = '=IMPORTXML("' + SpreadsheetApp.getActiveSheet().getRange('A1').getValue() + '?' + queryString + '","'+ SpreadsheetApp.getActiveSheet().getRange('A2').getValue() + '")';
  SpreadsheetApp.getActiveSheet().getRange('C1').setValue(cellFunction1);

  var cellFunction2 = '=IMPORTXML("' + SpreadsheetApp.getActiveSheet().getRange('A4').getValue() + '?' + queryString + '","'+ SpreadsheetApp.getActiveSheet().getRange('A5').getValue() + '")';
  SpreadsheetApp.getActiveSheet().getRange('C2').setValue(cellFunction2);
}

我不知道我应该在该代码中放入/替换什么。如果有人可以帮助我解释我应该改变什么以使其在我的工作表中工作/提供一些示例来说明一个人的外观,那将是一个巨大的帮助。

我很感激

【问题讨论】:

标签: google-apps-script


【解决方案1】:

您可以通过在 time-driven trigger 函数中使用 getFormula() 然后 setFormula() 来更新函数。这是来自相关SO post的代码sn-p:

/**
 * Go through all sheets in a spreadsheet, identify and remove all spreadsheet
 * import functions, then replace them a while later. This causes a "refresh"
 * of the "import" functions. For periodic refresh of these formulas, set this
 * function up as a time-based trigger.
 *
 * Caution: Formula changes made to the spreadsheet by other scripts or users
 * during the refresh period COULD BE OVERWRITTEN.
 *
 * From: https://stackoverflow.com/a/33875957/1677912
 */
function RefreshImports() {
  var lock = LockService.getScriptLock();
  if (!lock.tryLock(5000)) return;             // Wait up to 5s for previous refresh to end.
  // At this point, we are holding the lock.

  var id = "YOUR-SHEET-ID";
  var ss = SpreadsheetApp.openById(id);
  var sheets = ss.getSheets();

  for (var sheetNum=0; sheetNum<sheets.length; sheetNum++) {
    var sheet = sheets[sheetNum];
    var dataRange = sheet.getDataRange();
    var formulas = dataRange.getFormulas();
    var tempFormulas = [];
    for (var row=0; row<formulas.length; row++) {
      for (col=0; col<formulas[0].length; col++) {
        // Blank all formulas containing any "import" function
        // See https://regex101.com/r/bE7fJ6/2
        var re = /.*[^a-z0-9]import(?:xml|data|feed|html|range)\(.*/gi;
        if (formulas[row][col].search(re) !== -1 ) {
          tempFormulas.push({row:row+1,
                             col:col+1,
                             formula:formulas[row][col]});
          sheet.getRange(row+1, col+1).setFormula("");
        }
      }
    }

    // After a pause, replace the import functions
    Utilities.sleep(5000);
    for (var i=0; i<tempFormulas.length; i++) {
      var cell = tempFormulas[i];
      sheet.getRange( cell.row, cell.col ).setFormula(cell.formula)
    }

    // Done refresh; release the lock.
    lock.releaseLock();
  }
}

希望这会有所帮助。

【讨论】:

    【解决方案2】:

    我一直在做一些相关的事情,最后使用this StackOverFlow Post的代码解决了这个问题,但我需要添加一些额外的位。

    这对我来说效果不佳,因此我做了一些更改并添加了额外的日志记录以使其易于理解。是这样的:

    function RefreshImports() {
      var lock = LockService.getScriptLock();
      if (!lock.tryLock(5000)) return;             // Wait up to 5s for previous refresh to end.
      
      var now = new Date();
      // Show start time on log
      Logger.log("Starting Running at " + now.toLocaleTimeString());
      
      var url = "URL OF YOUR SHEET";
      var sheetName = "NAME OF YOUR SHEET";
      
      var ss = SpreadsheetApp.openByUrl(url);
      var sheet = ss.getSheetByName(sheetName);
    
        var dataRange = sheet.getDataRange();
        var formulas = dataRange.getFormulas();
        var tempFormulas = [];
        for (var row=0; row<formulas.length; row++) {
          for (var col=0; col<formulas[0].length; col++) {
            // Blank all formulas containing any "import" function
            // See https://regex101.com/r/bE7fJ6/2
            var re = /.*[^a-z0-9]import(?:xml|data|feed|html|range)\(.*/gi;
            if (formulas[row][col].search(re) !== -1 ) {
              tempFormulas.push({row:row+1,
                                 col:col+1,
                                 formula:formulas[row][col]});
              sheet.getRange(row+1, col+1).setFormula(""); //cleans up the formula
            }
            
          }
        }
        // After a pause, replace the import functions
            Utilities.sleep(500);
            for (var i=0; i<tempFormulas.length; i++) {
              var cell = tempFormulas[i];
              sheet.getRange( cell.row, cell.col ).setFormula(cell.formula);
              var nowLogger = new Date();     
              Logger.log("Update import from row " + cell.row + " col " + cell.col + " done at " + nowLogger.toLocaleTimeString());
              Utilities.sleep(1000); //adding to try to control the amount of parallel connections from the Sheet
            }
          
      
        // Show Finished time on log
      var now = new Date();
      Logger.log("Sources from URLs were last updated at " + now.toLocaleTimeString());
    
        // Done refresh; release the lock.
      lock.releaseLock();
      
    }

    然后我在 https://script.google.com/home/triggers 的项目中添加了 Time-Based 触发器,该触发器处理自动更新执行。

    我希望这会有所帮助!

    【讨论】:

    • 它实际上不起作用。我的意思是它确实不会刷新单元格,而使用随机数它可以工作:``` function getData() { var queryString = Math.random(); var Xpath_1 = "/html/body/text()"; var importXpath_1 = '=IMPORTXML("' + 'pde-racing.com/trams/…' + '?' + queryString + '";"'+ Xpath_1 + '")'; SpreadsheetApp.getActiveSheet().getRange('B39').setValue(importXpath_1); } ```
    【解决方案3】:

    它实际上不起作用。我的意思是它确实不会刷新单元格,而使用随机数它可以工作:

    function getData() {
      var queryString = Math.random();
    
      var Xpath_1 = "/html/body/text()";
      var importXpath_1 = '=IMPORTXML("' + 'http://www.pde-racing.com/trams/tram.php?id=999&valor=1&manega=Entrenament+1&dbTemps=Event999Ex.scdb&dbInscrits=Event999.scdb&name=&_=1616318271525' + '?' + queryString + '";"'+ Xpath_1 + '")';
      
      SpreadsheetApp.getActiveSheet().getRange('B39').setValue(importXpath_1);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多