AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / coding / 问题

问题[google-apps-script](coding)

Martin Hope
Doc
Asked: 2025-04-21 03:42:59 +0800 CST

forEach 显示红色括号,但脚本似乎正在运行

  • 7

我确信这是我的错误,但由于脚本可以正常工作,所以不确定这是否会在某个时候出现。我有 11 个选项卡,脚本会遍历前 9 个选项卡并隐藏所有没有数据的行,然后将每个选项卡的光标设置为 B4,但第 10 和 11 个选项卡除外,它们将设置为 A1。但是有一个红色的花括号,我不知道如何更正它。一个位于第一行末尾,对应的是带有 }); 的行。感谢您的帮助。

       function onOpen() {
  
  SpreadsheetApp.getActive().getSheets().forEach(function (s,index,array) {  //for each sheet
  
  if(index<9){ //if sortable page, not maps or docs
  var nameOfSheet= array[index].getName()
  var ssa = SpreadsheetApp.getActive().getSheetByName(nameOfSheet) //get active sheet
  var max = ssa.getMaxRows()//max rows for this sheet
  var last = ssa.getLastRow() //last row with data
  ssa.hideRows(last+1, max-last)
  }

  if(index>8){
      s.setActiveSelection("A1"); //set active cell for sheet to A1 if map or documentation sheet
    SpreadsheetApp.flush(); // Force this update to happen before moving to next sheet
    }else{
      s.setActiveSelection("B4"); //set active cell for sheet to B4 for other sheets
    SpreadsheetApp.flush(); // Force this update to happen before moving to next sheet
  }
  
  });
  var sheet = SpreadsheetApp.getActive().getSheetByName('Active(Date)'); //set back to first sheet
  var range = sheet.getRange('B4'); //put cursor on search box
  range.activate(); 
}
google-apps-script
  • 1 个回答
  • 58 Views
Martin Hope
Татьяна Со
Asked: 2025-04-16 04:14:45 +0800 CST

如何将新创建的文档保存在一个文件中?

  • 5

我正在根据模板创建几个 doc.file,并从工作表中获取数据。所有内容都保存在不同的文件中。请帮我把这些新文件保存到一个文档中。

function myFunction() {
  const docFile = DriveApp.getFileById("....."); //template file
  const tempFolder = DriveApp.getFolderById("...."); //folder for new files

  var list = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet(); //get an active    book, get an asset.sheet
  var l = list.getLastRow(); // get the last line

  for (var i = 9; i <= l; i++) {

    const tempFile = docFile.makeCopy(tempFolder);//make a copy of the template
    const tempDocFile = DocumentApp.openById(tempFile.getId()); //open a copy of the template
    const body = tempDocFile.getBody(); //get the body (text) of the copy file

    //getting variables from the table::
    var a1 = list.getRange(i, 1).getValue(); // get data from drain number i and column 1 -
    var a2 = list.getRange(i, 2).getValue();
    var a3 = list.getRange(i, 3).getValue();

    //replacing the necessary data in the text of the template copies:
    body.replaceText("{......}", a1);
    body.replaceText("{.....}", a2);
    body.replaceText("{....}", a3);

    //naming the created file:
    const newFileName = '.....' + a2; // assigning a name
    tempFile.setName(newFileName);

    tempDocFile.saveAndClose(); //save and close
  }
}

我不是程序员,在网上找了个脚本自己改了一下,不知道具体怎么改。

google-apps-script
  • 1 个回答
  • 115 Views
Martin Hope
Matt Sirkin
Asked: 2025-04-05 00:56:26 +0800 CST

突然收到 GmailApp.SendEmail 错误

  • 7

我有一个使用了很长时间的 Appscript 程序。它会给我发送一封带有附件的电子邮件。附件是一份已导出为 xlsx 格式的 Google Sheet。

突然,我收到错误:异常:服务不可用:Gmail

我每天使用它大约 10 次,因此我认为我没有达到任何速率限制。

这是一个简单的例子:

let spreadsheet = SpreadsheetApp.getActive();
let spreadsheetId = spreadsheet.getId();
let sheetName = spreadsheet.getActiveSheet().getName();

let sheetId = spreadsheet.getSheetByName(sheetName).getSheetId();
let url = `https://docs.google.com/spreadsheets/d/${spreadsheetId}/export?format=xlsx&gid=${sheetId}`;
let params = { method: "GET", headers: { "authorization": "Bearer " + ScriptApp.getOAuthToken() } };
let response = UrlFetchApp.fetch(url, params).getBlob().setName(sheetName);
let email = "[email protected]";

GmailApp.sendEmail(email, 'subject', '', {
  attachments: {
    fileName: 'filename.xlsx',
    content: response.getBytes(),
    mimeType: `application/xlsx`,
  }
});

有趣的是,如果我删除附件,它就会起作用。我也尝试了不同的附件和格式,但都返回了相同的错误。我也在隐身模式下尝试过。我非常感谢任何帮助!谢谢!

google-apps-script
  • 1 个回答
  • 67 Views
Martin Hope
rg_
Asked: 2025-03-28 15:07:48 +0800 CST

如何提高 Google Apps Script 的效率(向 Salesforce 获取请求,将数据写入 Google 表格)

  • 5

我有一个 AppSheet 应用,它使用 Google Sheet 作为其表格的数据源,尽管 Google Sheet 的底层数据源是 Salesforce。Salesforce sObject 非常庞大(660 多列,数十万条记录),因此我无法使用 AppSheet/Salesforce 集成,因为当我只需要每个用户一小部分数据时,同步所有数据效率非常低。

我正在使用 Google Apps 脚本向 Salesforce 发送 GET 请求,该请求返回“Workers”的有效负载,通常少于一百行,每行 10 列。GET 请求选择应用程序登录用户的“地盘”中的 Workers。

Workers 表保存所有用户的草皮,因为在任何给定时间可能有多个用户登录,但应用程序仅在 UI 中呈现当前登录用户的草皮。

应用程序中没有可供用户修改工人记录的用户界面,只需要读取和选择工人记录以更新相关表(该表会写回 Salesforce)即可。因此,Salesforce 始终拥有工人的最新更新数据,我不需要与 Google 表格进行双向同步。

脚本可以运行,但速度非常慢。对于一组约 100 条记录(每条记录 10 列)的记录,整个 loadTurf 过程大约需要 30 秒,我正在尝试找出如何改进脚本以使其更快。我无法控制 Salesforce 身份验证/JWT 交换/GET 请求部分的速度,但该部分仅需 3-5 秒,其余部分是 API 有效负载返回后发生的处理:检查重复项、删除需要用新数据覆盖的行以及将新数据写入工作表。

我知道一定有更快的方法来做到这一点。检查重复项和删除部分似乎特别低效,每次用 迭代一行forEach,但我无法找到批量处理删除的方法,因为草皮理论上可能处于非连续行中。有没有办法一次性删除整个过滤范围,而无需一次迭代一行?根据 Salesforce 有效负载检查每行是否有更新的列似乎比直接删除所有行并粘贴 Salesforce 返回的新行更慢。

无论如何,这是我的代码,最慢的部分似乎是检查重复和删除操作,对于一批 100 条记录,每个操作大约需要 10-11 秒。有人能建议一些改进方法吗?

const fieldsArray = [ ... list of fields ... ];
const ss = SpreadsheetApp.openByUrl( ... url ...);
const workers = ss.getSheetByName( ... sheetName ...); 
const contactIds = workers.getRange("A2:A").getValues().flat().filter(Boolean);

async function loadUserTurf(employer) {
  let records;
  if (employer) {
    try {
      const qp = new QueryParameters();
      qp.setSelect(fieldsArray.toString());
      qp.setFrom("Contact");
      qp.setWhere(`Employer_Name_Text__c = \'${employer}\' AND Active_Worker__c = TRUE`);

      records = await get(qp);
      setUserTurf(employer, records);
    } catch (err) {
      logErrorFunctions('loadUserTurf', employer, records, err);
    }

  } else {
    console.log(`loadUserTurf > 24: no employer provided`);
  }
  
}

const confirmUniqueContactId = (id) => !contactIds.includes(id);

function appendNewRows(data, sheet) { // data = array of objects
    try {
      data.forEach(obj => {
        if (confirmUniqueContactId(obj.Id)) {
          // flatten object to array
          const row = Object.values(obj).slice(1);
          sheet.appendRow(row);
        }        
      })
    } catch (err) {
      logErrorFunctions('appendNewRows', [data, sheet], '', err);
    }
}

function setUserTurf(employerName, payload) {
  // Check for matching rows -- has this turf been pulled before?
  // create an array of all matching row indices so we can delete them
  // and replace them with fresh data from Salesforce

  const allData = workers.getDataRange().getValues();
  const turfIndices = allData.map((row, index) => {
    if (row[3] === employerName) {
      return index + 1;
    }
  }).filter(n => n); // remove null values
  
  // If no matching rows found (user's first login)
  // create new rows to append the payload from Salesforce
  if (!turfIndices.length) {
    // append new rows with data from payload from loadTurf function
    try {
      appendNewRows(payload, workers);    
    } catch (err) {
      console.log(err);
      logErrorFunctions('setUserTurf', turfIndices, '', err);
    }
  } else {
    // otherwise, delete all existing rows in that turf and replace them with fresh data from Salesforce
    // because checking for differences at the individual cell level seems even more inefficient?
    try {
      turfIndices.forEach(index => workers.deleteRow(index));
      // append new rows with data from payload from loadTurf function
      appendNewRows(payload, workers); 
    } catch (err) {
      logErrorFunctions('setUserTurf', turfIndices, '', err);
    }
  }
}
google-apps-script
  • 1 个回答
  • 54 Views
Martin Hope
melrin
Asked: 2025-02-19 18:11:32 +0800 CST

Google 脚本在编辑特定范围的单元格时在单元格中显示日期和时间

  • 3

我正在尝试使用编辑特定单元格范围的日期和时间来更新单元格。

我一直在摆弄下面的代码,但检查执行日志后,触发器每次都失败。

我哪里错了?

function onEdit(e) {
  var range1 = e.range.getSheet().getRange("D260:D264");
  var range2 = e.range.getSheet().getRange("P260:P264");
  var range3 = e.range.getSheet().getRange("S260:S264");
  var range4 = e.range.getSheet().getRange("AE260:AE264");
  var range5 = e.range.getSheet().getRange("AJ260:AJ264");
  var range6 = e.range.getSheet().getRange("D53");
  var range7 = e.range.getSheet().getRange("N53");

  if (e.range.intersects(range1) || e.range.intersects(range2) || e.range.intersects(range3) || e.range.intersects(range4) || e.range.intersects(range5) || e.range.intersects(range6) || e.range.intersects(range7)) {

  var dateCell = e.range.getSheet().getRange("W247"); 

  dateCell.setValue(new Date());

  }

}
google-apps-script
  • 1 个回答
  • 33 Views
Martin Hope
Dennis
Asked: 2025-02-05 04:07:57 +0800 CST

如何在选择菜单后查看 Google Apps 脚本日志

  • 5

我有一个脚本,它从 JDBC 连接获取输入并将其写入工作表。有时此操作的结果并非预期结果,因此我在脚本的关键点处散布了如下代码:

          Logger.log("Trying to delete rows, received: "
                      +  e.message) ;
              Logger.log("   Continuing.") ;

当我从脚本编辑器的“运行”按钮运行此类代码时,我可以毫不费力地看到最新的执行日志 - 它就在我面前。但是当我从像这样创建的菜单中运行相同的代码时:

function onOpen() {
    var menuItems ;
    var spreadsheet = SpreadsheetApp.getActive();
    var user = Session.getEffectiveUser().getEmail() ;
    var validUsers = [ validUsersList ]

    if (spreadsheet.getDataRange().canEdit()) {
        menuItems = [
            {name: 'Process all streams' , functionName: 'processAllStreams'}
            , {name: 'Build covered artists'           , functionName: 'rebuildCoversSheet'}
            //, {name: 'Add to song list'              , functionName: 'buildSongList'}
            //, {name: 'Process selective streams'       , functionName: 'processStreams'}
            //, {name: 'Move suggestions to top'         , functionName: 'moveSuggestionsToTop'}
            , {name: 'Go to bottom'                    , functionName: 'showBottomRange'}
            , {name: 'New livestream details'          , functionName: 'getNewLivestreamDetails'}
                ];
        spreadsheet.addMenu('Process it', menuItems);

             etc.

从该菜单运行时,我看不到日志。我已进入编辑器并在那里检查;它似乎不知道在开发环境之外运行的脚本。

我必须做什么才能看到这些日志?我知道有一个云日志选项,但看起来设置起来并不那么简单。文档中没有提到通过菜单或脚本编辑器运行脚本的限制。文档 确实提到了一些限制:

These logs are intended for simple checks during development and debugging, and do not persist very long.

但他们似乎没有解决这个问题。有简单的方法吗?

顺便说一句,对于某些正在执行的操作,从脚本编辑器运行不是一个选项。原因是其中涉及提示和对话框(getUi.prompt() 等),而这些在脚本编辑器模式下是不允许的。所以目前这是一个两难的局面。

编辑-添加了可测试脚本

以下代码:

function onOpen() {
    var menuItems = [
            { name: 'Make a log entry', functionName: 'makeEntry' }
        ];
        SpreadsheetApp.getActive().addMenu('Process it', menuItems);
}

function makeEntry() {
  Logger.log('here you go....') ;
}

如果您创建一个新的 Google Sheet 并将此代码添加到脚本编辑器中:

从脚本编辑器运行脚本,您将看到创建的日志条目。

从创建(“处理它”)菜单运行脚本,我找不到该日志条目。

google-apps-script
  • 1 个回答
  • 50 Views
Martin Hope
Spencer
Asked: 2025-02-04 05:43:32 +0800 CST

Google Forms 在 Apps Script 中设置正则表达式

  • 5

我正在通过 Apps Script 创建 Google 表单,需要设置一个字段以仅接受美国 10 位电话号码。我发现这个正则表达式在通过表单编辑器设置时有效:^(\+0?1\s)?\(?\d{3}\)?[\s.-]\d{3}[\s.-]\d{4}$。

但同样,我需要通过 Apps Script 来实现这一点。我的代码片段如下:

let form = FormApp.create("new Order");
let phoneNumber = form.addTextItem().setTitle("Textable phone number").setRequired(true);
  phoneNumber.setValidation(FormApp.createTextValidation()
      .requireTextMatchesPattern("^(\+0?1\s)?\(?\d{3}\)?[\s.-]\d{3}[\s.-]\d{4}$")
      .build());

Exception: Invalid data updating form.当我将其更改为脚本运行并完成时,这会引发错误.requireTextMatchesPattern(/^(\+0?1\s)?\(?\d{3}\)?[\s.-]\d{3}[\s.-]\d{4}$/),但随后无法填写表格,因为标准电话号码会引发错误must match pattern.

那么,如何在 Apps Script 中设置能够正确允许输入的正则表达式模式?

google-apps-script
  • 2 个回答
  • 91 Views
Martin Hope
mrC0der
Asked: 2025-02-03 21:02:51 +0800 CST

尝试分配函数变量谷歌应用脚​​本

  • 7

我对 Google Apps Script 还比较陌生,但我学得很快,现在我正尝试使用菜单调用一个函数,但我似乎找不到如何在该菜单项中分配变量。我的代码如下:

ui.createMenu('foo')
  .addItem('bar', 'foobar')

function foobar(bar) {
  if (bar == 1) {
    //something
  }
  else if (bar == 2) {
    //something else
  }
}

我正在尝试在 '.addItem('bar', 'foobar')' 中分配 'bar'

google-apps-script
  • 1 个回答
  • 58 Views
Martin Hope
T White
Asked: 2025-01-22 11:45:49 +0800 CST

如何使用 Apps 脚本从网站提取数据[重复]

  • 2
此问题这里已有答案:
使用 Google Apps Script 抓取动态网页 (1 个回答)
从使用 JavaScript 的网站抓取数据到 Google 表格 (2 个答案)
16 小时前关闭。

目标:
从以下网址提取数据: https: //www.olg.ca/en/home.html

LottoMax 头奖金额 & 最高百万数额
Lotto649 金球金额
LOTTARIO 头奖金额

我的问题:
金额是在 JavaScript 中动态呈现的,因此无法使用 ImportXML。我在 Apps Script 中创建了一个函数,但我没有看到用于获取数据的 API,因此它不起作用。

还有其他方法可以获取这些数据吗?如有任何见解,我将不胜感激。谢谢。

google-apps-script
  • 1 个回答
  • 46 Views
Martin Hope
user3225844
Asked: 2025-01-22 11:13:11 +0800 CST

如何修复 AppScript 数组值比较错误(值的长度不同)

  • 5

我有一个 google sheet appscript 宏,用于比较某个联赛中一组球队的每周得分。它通过比较一组类别的得分来检查哪支球队每周会击败对方。有一些逻辑可以设置某些类别的得分是高还是低。该宏在几乎所有情况下都能正确地比较得分,但我最终发现了一个无法解决的错误。

  // Get all relevant data from the stat sheet in one go
  const statsRange = statSheet.getRange('C8:C234').offset(0, weeks);
  const statsData = statsRange.getValues();

  // Iterate through teams (assuming 12 teams)
  for (let i = 0; i <= 11; i++) {
    for (let j = 0; j <= 11; j++) {
      if (i===11&&j===11) {break}
      if (j===i) {j=j+1;}
      let score = 0;

      // Iterate through stats for each team pair, comparing and calculating score. 
     Scores are across 19 rows per team in the data set. There are 15 relevant rows. 

      for (let k = 0; k <= 15; k++) { 
        var homeStat = statsData[(19 * i) + k]; 
        var awayStat = statsData[(19 * j) + k];

        // Skip some stats and handle some differently
        if (k === 0 || k === 1 || k === 3 || k === 4) {continue}
        else if (k === 13||k === 14) {
          score += (homeStat < awayStat) ? 1 : (homeStat > awayStat) ? -1 : 0;
        } else {
          score += (homeStat > awayStat) ? 1 : (homeStat < awayStat) ? -1 : 0;
        }
        console.log(i, j, k, homeStat, awayStat, score)
      }

输入数据集示例

细胞 价值
C198 180
C199 409
C200 0.44
C201 114
C202 148
C203 0.77
C204 68
C205 542
C206 43
C207 174
C208 107
C209 二十八
C210 14
C211 55
C212 0
C213 0
C214 7
C215
C216
C217 130
C218 273
C219 0.476
C220 65
C221 82
C222 0.793
C223 三十五
C224 360
C225 四十二
C226 142
C227 87
C228 31
C229 二十五
C230 52
C231 0
C232 1
C233 7

出于某种原因,如果 HomeStat 和 AwayState 的数量级不同,则此比较会产生相反的结果。示例日志/输出:i 和 j 是工作表中的团队。k 是统计类别。主场和客场统计数据是每个团队针对该类别的输入。分数应根据逻辑增加或减少。k = 10 是错误。当主场得分小于客场得分时,它会增加。

|time|log|i|j|k|home stat|away stat|score|
6:59:04 PM  Info    11 10 2 [ 0.476 ] [ 0.44 ] 1
6:59:04 PM  Info    11 10 5 [ 0.793 ] [ 0.77 ] 2
6:59:04 PM  Info    11 10 6 [ 35 ] [ 68 ] 1
6:59:04 PM  Info    11 10 7 [ 360 ] [ 542 ] 0
6:59:04 PM  Info    11 10 8 [ 42 ] [ 43 ] -1
6:59:04 PM  Info    11 10 9 [ 142 ] [ 174 ] -2
6:59:04 PM  Info    **11 10 10 [ 87 ] [ 107 ] -1**
6:59:04 PM  Info    11 10 11 [ 31 ] [ 28 ] 0
6:59:04 PM  Info    11 10 12 [ 25 ] [ 14 ] 1
6:59:04 PM  Info    11 10 13 [ 52 ] [ 55 ] 2
6:59:04 PM  Info    11 10 14 [ 0 ] [ 0 ] 2
6:59:04 PM  Info    11 10 15 [ 1 ] [ 0 ] 3

逻辑始终将 +1 应用于长度较短的分数(2 比 3 个数字),无论主场还是客场。如果两个分数都是 2 或 3 个数字,则得分正确。

google-apps-script
  • 1 个回答
  • 38 Views

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    重新格式化数字,在固定位置插入分隔符

    • 6 个回答
  • Marko Smith

    为什么 C++20 概念会导致循环约束错误,而老式的 SFINAE 不会?

    • 2 个回答
  • Marko Smith

    VScode 自动卸载扩展的问题(Material 主题)

    • 2 个回答
  • Marko Smith

    Vue 3:创建时出错“预期标识符但发现‘导入’”[重复]

    • 1 个回答
  • Marko Smith

    具有指定基础类型但没有枚举器的“枚举类”的用途是什么?

    • 1 个回答
  • Marko Smith

    如何修复未手动导入的模块的 MODULE_NOT_FOUND 错误?

    • 6 个回答
  • Marko Smith

    `(表达式,左值) = 右值` 在 C 或 C++ 中是有效的赋值吗?为什么有些编译器会接受/拒绝它?

    • 3 个回答
  • Marko Smith

    在 C++ 中,一个不执行任何操作的空程序需要 204KB 的堆,但在 C 中则不需要

    • 1 个回答
  • Marko Smith

    PowerBI 目前与 BigQuery 不兼容:Simba 驱动程序与 Windows 更新有关

    • 2 个回答
  • Marko Smith

    AdMob:MobileAds.initialize() - 对于某些设备,“java.lang.Integer 无法转换为 java.lang.String”

    • 1 个回答
  • Martin Hope
    Fantastic Mr Fox msvc std::vector 实现中仅不接受可复制类型 2025-04-23 06:40:49 +0800 CST
  • Martin Hope
    Howard Hinnant 使用 chrono 查找下一个工作日 2025-04-21 08:30:25 +0800 CST
  • Martin Hope
    Fedor 构造函数的成员初始化程序可以包含另一个成员的初始化吗? 2025-04-15 01:01:44 +0800 CST
  • Martin Hope
    Petr Filipský 为什么 C++20 概念会导致循环约束错误,而老式的 SFINAE 不会? 2025-03-23 21:39:40 +0800 CST
  • Martin Hope
    Catskul C++20 是否进行了更改,允许从已知绑定数组“type(&)[N]”转换为未知绑定数组“type(&)[]”? 2025-03-04 06:57:53 +0800 CST
  • Martin Hope
    Stefan Pochmann 为什么 {2,3,10} 和 {x,3,10} (x=2) 的顺序不同? 2025-01-13 23:24:07 +0800 CST
  • Martin Hope
    Chad Feller 在 5.2 版中,bash 条件语句中的 [[ .. ]] 中的分号现在是可选的吗? 2024-10-21 05:50:33 +0800 CST
  • Martin Hope
    Wrench 为什么双破折号 (--) 会导致此 MariaDB 子句评估为 true? 2024-05-05 13:37:20 +0800 CST
  • Martin Hope
    Waket Zheng 为什么 `dict(id=1, **{'id': 2})` 有时会引发 `KeyError: 'id'` 而不是 TypeError? 2024-05-04 14:19:19 +0800 CST
  • Martin Hope
    user924 AdMob:MobileAds.initialize() - 对于某些设备,“java.lang.Integer 无法转换为 java.lang.String” 2024-03-20 03:12:31 +0800 CST

热门标签

python javascript c++ c# java typescript sql reactjs html

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve