Node.js 如何复制谷歌表单并使数据验证保持完整?

Node.js 如何复制谷歌表单并使数据验证保持完整?,node.js,google-sheets,google-sheets-api,Node.js,Google Sheets,Google Sheets Api,我有一个谷歌电子表格模板,有两张表,数据输入和数据验证。数据验证工作表中有许多列,这些列的有效值与数据输入工作表中的列相匹配。一切正常。我需要将这两张表复制到测试中的表中(SUT)。我正在使用sheets API复制这两张图纸。我首先复制数据验证表,然后复制数据输入表。这是代码,这似乎是可行的 const request = { spreadsheetId :fromSpreadsheetId, sheetId : fromSheetId, resource:{

我有一个谷歌电子表格模板,有两张表,
数据输入
数据验证
数据验证
工作表中有许多列,这些列的有效值与
数据输入
工作表中的列相匹配。一切正常。我需要将这两张表复制到测试中的
表中
(SUT)。我正在使用sheets API复制这两张图纸。我首先复制
数据验证
表,然后复制
数据输入
表。这是代码,这似乎是可行的

 const request =  {
    spreadsheetId :fromSpreadsheetId,
    sheetId : fromSheetId,
    resource:{
      destinationSpreadsheetId: toSpreadsheetId,
    },
  }
  const result = await  _sheetService.spreadsheets.sheets.copyTo(request)
在我的SUT上,这两个表都会出现,
数据输入
表包含所有预期的下拉列表,并且它们都具有正确的值。看起来很完美。问题是,当您从它选择的任何列的任何下拉列表中选择一个项目并输入正确的值,然后添加一个红色三角形和一条消息,说明输入了无效的值。如果列具有拒绝设置,则会删除该值并显示错误对话框

图中显示了我已经从下拉列表中选择了视频课程的两个单元格

如果我进入并重新选择要验证的列,请使用
Data→DataValidation…
然后点击
保存
按钮,列开始工作,这样看起来所有内容都正确,但工作表不这样认为。是否有任何编程方式可以强制执行我手动执行的上述过程?在
sheets.copyTo
方法中,我还需要做些什么才能使它正常工作

编辑 这个项目是用Node.js编写的,它结合了TypeScript和JavaScript。有关与工作表API对话和在电子表格之间复制工作表的较低级别代码,请参见。方法是
copySheetFromTo
,它位于文件的底部

具有公共视图权限的

具有公共编辑权限的

使用上述两个文件复制图纸的文件位于文件底部,名称开头有“调试测试”(从第209行开始)

  • 您希望复制包含数据验证的工作表
  • 使用复制的工作表时,数据验证下拉菜单中会出现错误。
    • 您想删除此错误
如果我的理解是正确的,那么这个答案呢?在这个答案中,为了消除错误,我覆盖了复制的工作表的数据验证,作为一种解决方法。请将此视为几种变通方法之一

您的情况的流程如下所示

流量:
  • 使用Spreadsheet.get方法从源电子表格(“DataValidationTest”)中的
    数据输入表中检索所有数据验证
  • 将源电子表格(“DataValidationTest”)中的
    数据输入表
    复制到目标电子表格(“公共目标表”)
  • 复制
    数据条目
    的工作表后,将工作表名称从
    数据条目副本
    重命名为
    数据条目
  • 然后,使用spreadsheet.batchUpdate方法将检索到的数据验证覆盖到
    数据输入表中。
    
    • 在这种情况下,由spreadsheet.get方法检索的数据验证结构与spreadsheet.batchUpdate方法的结构几乎相同。这个变通方法使用了这个
  • 将源电子表格(“DataValidationTest”)中的
    数据验证
    表复制到目标电子表格(“公共目标表”)
  • 数据验证副本的工作表名称重命名为
    数据验证
  • 示例脚本: 测试此脚本时,请设置变量。我认为
    sheet.spreadsheets.get()
    sheet.spreadsheets.batchUpdate()
    sheet.spreadsheets.sheets.copyTo()
    与脚本的
    sheetOps
    相同

    const srcSpreadsheet = "###";  // Please set this.
    const tempDestSheetId = "###";  // Please set this.
    const srcDataEntrySheetId = 0;  // Please set this.
    const srcDataValidationSheetId = 123456789;  // Please set this.
    
    let dataValidation = await sheet.spreadsheets.get({
      spreadsheetId: srcSpreadsheet,
      ranges: ["Data Entry"],
      fields: "sheets/data/rowData/values/dataValidation"
    });
    let data = dataValidation.data.sheets[0].data;
    let rows = [];
    for (let i = 0; i < data.length; i++) {
      if (data[i].rowData) {
        rows = data[i].rowData;
        break;
      }
    }
    
    sheet.spreadsheets.sheets.copyTo(
      {
        spreadsheetId: srcSpreadsheet,
        sheetId: srcDataEntrySheetId,
        resource: { destinationSpreadsheetId: tempDestSheetId }
      },
      (err, res) => {
        sheet.spreadsheets.batchUpdate(
          {
            spreadsheetId: tempDestSheetId,
            resource: {
              requests: [
                {
                  updateSheetProperties: {
                    fields: "title,sheetId",
                    properties: { sheetId: res.data.sheetId, title: "Data Entry" }
                  }
                },
                {
                  updateCells: {
                    rows: rows,
                    range: { sheetId: res.data.sheetId },
                    fields: "dataValidation"
                  }
                }
              ]
            }
          },
          (er, re) => {
            if (err) {
              console.error(er);
              return;
            }
            console.log(re.data);
          }
        );
      }
    );
    
    let result1 = await sheet.spreadsheets.sheets.copyTo({
      spreadsheetId: srcSpreadsheet,
      sheetId: srcDataValidationSheetId,
      resource: { destinationSpreadsheetId: tempDestSheetId }
    });
    
    let result2 = await sheet.spreadsheets.batchUpdate({
      spreadsheetId: tempDestSheetId,
      resource: {
        requests: [
          {
            updateSheetProperties: {
              fields: "title,sheetId",
              properties: {
                sheetId: result1.data.sheetId,
                title: "Data Validation"
              }
            }
          }
        ]
      }
    });
    
    console.log(result2.data);
    
    const srcSpreadsheet=“####”;//请把这个放好。
    const tempDestSheetId=“####”;//请把这个放好。
    const srcDataEntrySheetId=0;//请把这个放好。
    const srcDataValidationSheetId=123456789;//请把这个放好。
    让dataValidation=wait sheet.spreadsheets.get({
    电子表格ID:SRC电子表格,
    范围:[“数据输入”],
    字段:“工作表/数据/行数据/值/数据验证”
    });
    让data=dataValidation.data.sheets[0].data;
    让行=[];
    for(设i=0;i{
    sheet.spreadsheets.batchUpdate(
    {
    电子表格ID:tempDestSheetId,
    资源:{
    要求:[
    {
    updateSheetProperties:{
    字段:“标题,表单ID”,
    属性:{sheetId:res.data.sheetId,标题:“数据输入”}
    }
    },
    {
    更新单元:{
    行:行,
    范围:{sheetId:res.data.sheetId},
    字段:“数据验证”
    }
    }
    ]
    }
    },
    (呃,re)=>{
    如果(错误){
    控制台错误(er);
    返回;
    }
    控制台日志(关于数据);
    }
    );
    }
    );
    让result1=wait sheet.spreadsheets.sheets.copyTo({
    电子表格ID:SRC电子表格,
    sheetId:srcDataValidationSheetId,
    资源:{destinationSpreadsheetId:tempDestSheetId}
    });
    让result2=wait sheet.spreadsheets.batchUpdate({
    电子表格ID:tempDestSheetId,
    资源:{
    要求:[
    {
    updateSheetProperties:{
    字段:“标题,表单ID”,
    特性:{
    sheetId:result1.data.sheetId,
    钛