Google Sheets API v4 Error: 'Invalid requests[0].addFilterView: No grid with id: 2'

Google Sheets API v4 Error: 'Invalid requests[0].addFilterView: No grid with id: 2'

通过 Google Sheets API v4 添加过滤视图。我检查了许多不同的 SO 帖子和其他资源,但我找不到符合我情况的解释。

我已经四次检查了这些传播sheet,它们都有 sheet 的 sheetId 为 2。我有 运行 代码在多个不同的文件上,并收到此错误。当我 运行 使用 sheetId: 0 的某些文件上的代码时,我会收到相同的错误消息 'Invalid requests[0].addFilterView: No grid with id: 0'

代码如下:

我的实际生产价差sheet

const request = {
        spreadsheetId: '1qWoAjFHik5oJ8_hXTatEgVj5sVExxQWxgFVCM_uHwXE',
        resource: {
            requests: [{
                "addFilterView": {
                    filter: {
                        filterViewId: 11,
                        title: 'Claims Without A Status',
                        range: {
                            sheetId: 2,
                            startRowIndex: 0,
                            endRowIndex: 50,
                            startColumnIndex: 0,
                            endColumnIndex: 3
                        },
                        filterSpecs: [
                            {
                                filterCriteria: {
                                    condition: {
                                        type: 'BLANK',
                                        values: []
                                    }
                                },
                                columnIndex: 1
                            }
                        ]
                    }
                }
            }]
        }
    }

    sheets.spreadsheets.batchUpdate(request).then(res => console.log(res)).catch(err => console.log(err))

这会产生:

errors: [
    {
      message: 'Invalid requests[0].addFilterView: No grid with id: 2',
      domain: 'global',
      reason: 'badRequest'
    }
  ]

一个测试我 运行 在另一个 sheet:

const request = {
        spreadsheetId: '1Fnu1s2DEZaSIX94rJug2sbmeseHO7tQ_M9nJX4rvPHE',
        resource: {
            requests: [{
                "addFilterView": {
                    filter: {
                        filterViewId: 11,
                        title: 'Claims Without A Status',
                        range: {
                            sheetId: 2,
                            startRowIndex: 0,
                            endRowIndex: 50,
                            startColumnIndex: 0,
                            endColumnIndex: 3
                        },
                        filterSpecs: [
                            {
                                filterCriteria: {
                                    condition: {
                                        type: 'BLANK',
                                        values: []
                                    }
                                },
                                columnIndex: 1
                            }
                        ]
                    }
                }
            }]
        }
    }

    sheets.spreadsheets.batchUpdate(request).then(res => console.log(res)).catch(err => console.log(err))

出品:

[
    {
      message: 'Invalid requests[0].addFilterView: No grid with id: 2',
      domain: 'global',
      reason: 'badRequest'
    }
  ]

但这段代码确实有效:

const request = {
        spreadsheetId: '1Fnu1s2DEZaSIX94rJug2sbmeseHO7tQ_M9nJX4rvPHE',
        resource: {
            requests: [{
                "addFilterView": {
                    filter: {
                        filterViewId: 12,
                        title: 'Claims Without A Status',
                        range: {
                            sheetId: 0,
                            startRowIndex: 0,
                            endRowIndex: 50,
                            startColumnIndex: 0,
                            endColumnIndex: 3
                        },
                        filterSpecs: [
                            {
                                filterCriteria: {
                                    condition: {
                                        type: 'BLANK',
                                        values: []
                                    }
                                },
                                columnIndex: 1
                            }
                        ]
                    }
                }
            }]
        }
    }

    sheets.spreadsheets.batchUpdate(request).then(res => console.log(res)).catch(err => console.log(err))

出品:

status: 200,
  statusText: 'OK',
  request: {
    responseURL: 'https://sheets.googleapis.com/v4/spreadsheets/1Fnu1s2DEZaSIX94rJug2sbmeseHO7tQ_M9nJX4rvPHE:batchUpdate'
  }

所以,我想,第二个索引的东西,尽管两个 sheet 中至少有 6 个 sheet(这意味着总会有一个 sheet 和 index/id 的 2,对吧?)。因此,我尝试了 运行 sheetId: 0 代码与我的产品 sheet。代码:

const request = {
        spreadsheetId: '1qWoAjFHik5oJ8_hXTatEgVj5sVExxQWxgFVCM_uHwXE',
        resource: {
            requests: [{
                "addFilterView": {
                    filter: {
                        filterViewId: 12,
                        title: 'Claims Without A Status',
                        range: {
                            sheetId: 0,
                            startRowIndex: 0,
                            endRowIndex: 50,
                            startColumnIndex: 0,
                            endColumnIndex: 3
                        },
                        filterSpecs: [
                            {
                                filterCriteria: {
                                    condition: {
                                        type: 'BLANK',
                                        values: []
                                    }
                                },
                                columnIndex: 1
                            }
                        ]
                    }
                }
            }]
        }
    }

    sheets.spreadsheets.batchUpdate(request).then(res => console.log(res)).catch(err => console.log(err))

出品:

errors: [
    {
      message: 'Invalid requests[0].addFilterView: No grid with id: 0',
      domain: 'global',
      reason: 'badRequest'
    }
  ]

所以,即使情况相同,我也会从不同的传播sheet 得到相互矛盾的反应。对于任何价差 sheet 甚至存在它必须有一个 sheet,这意味着在 index/id 0.

处总是会有一个 sheet

编辑

我试图在两个不同的传播sheets 上尝试这个:我一直在使用的旧传播sheet 和我刚刚创建的另一个测试传播sheet。 api 调用失败,旧价差 sheet 的消息相同,但 api 调用对新价差 sheet 有效,就像上面的一样。

这可以归结为 sheetId 在开始时被静态分配。如果您创建了几个 sheet,删除了两个,然后再创建更多,sheet 数字将递增到之前的最高值,即最后一个 sheet,即使您删除了那些其他 sheets。因此,例如,如果您有 Sheet1 Sheet2 和 Sheet3,如果您删除 Sheet3 并创建另一个 sheet,下一个 sheet 将是 Sheet4,您将使用 Sheet1 Sheet2 Sheet4。这让我相信我的旧文件中可能会发生类似的事情。我在那些旧的中删除并创建了很多 sheet。

编辑 2

我试图向测试 sheet 添加一个新的 sheet 并将过滤器视图应用于 sheetId 1,但我收到了错误消息 No grid with id: 1.我无法想象这里发生了什么。这似乎是一个错误。

我发现了问题。 sheetId 需要是 sheets 属性中的 sheetId,而不是 sheets 列表中 sheet 的索引。官方文档另有说明,但具有误导性。但是,我成功地找到了我的 sheet 之一的 sheetId 和 运行 代码。成功的代码如下所示:

const fs = require('fs');
const readline = require('readline');
const {google} = require('googleapis');
const SCOPES = ['https://www.googleapis.com/auth/spreadsheets'];
const TOKEN_PATH = 'token.json';

fs.readFile('credentials.json', (err, content) => {
  if (err) return console.log('Error loading client secret file:', err);
  authorize(JSON.parse(content), listMajors);
});

function authorize(credentials, callback) {
  const {client_secret, client_id, redirect_uris} = credentials.installed;
  const oAuth2Client = new google.auth.OAuth2(
      client_id, client_secret, redirect_uris[0]);

  fs.readFile(TOKEN_PATH, (err, token) => {
    if (err) return getNewToken(oAuth2Client, callback);
    oAuth2Client.setCredentials(JSON.parse(token));
    callback(oAuth2Client);
  });
}

function getNewToken(oAuth2Client, callback) {
  const authUrl = oAuth2Client.generateAuthUrl({
    access_type: 'offline',
    scope: SCOPES,
  });
  console.log('Authorize this app by visiting this url:', authUrl);
  const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout,
  });
  rl.question('Enter the code from that page here: ', (code) => {
    rl.close();
    oAuth2Client.getToken(code, (err, token) => {
      if (err) return console.error('Error while trying to retrieve access token', err);
      oAuth2Client.setCredentials(token);
      // Store the token to disk for later program executions
      fs.writeFile(TOKEN_PATH, JSON.stringify(token), (err) => {
        if (err) return console.error(err);
        console.log('Token stored to', TOKEN_PATH);
      });
      callback(oAuth2Client);
    });
  });
}

async function listMajors(auth) {
  const sheets = google.sheets({version: 'v4', auth});

    const allSheets = await sheets
        .spreadsheets
            .get({ spreadsheetId: '1qWoAjFHik5oJ8_hXTatEgVj5sVExxQWxgFVCM_uHwXE' })

    const sheetIndicies = {
        Audit: null,
        Billing: null,
        Closed: null
    }

    const sheetInfoArr = []

    allSheets.data.sheets.forEach(sheet => {
        if (sheet.properties.title === 'Audit' || sheet.properties.title === 'Billing' || sheet.properties.title === 'Closed') {
            sheetIndicies[sheet.properties.title] = sheet.properties.sheetId

            const { properties } = sheet
            const { gridProperties } = properties

            sheetInfoArr.push({
                sheetId: properties.index,
                startRowIndex: 0,
                endRowIndex: gridProperties.rowCount,
                startColumnIndex: 0,
                endColumnIndex: gridProperties.columnCount,
                name: sheet.properties.title
            })
        }
    })

    const request = {
        spreadsheetId: '1qWoAjFHik5oJ8_hXTatEgVj5sVExxQWxgFVCM_uHwXE',
        resource: {
            requests: [{
                "addFilterView": {
                    filter: {
                        filterViewId: 33,
                        title: 'Claims Without A Status 33',
                        range: {
                            sheetId: 513982100,
                            startRowIndex: 0,
                            endRowIndex: 50,
                            startColumnIndex: 0,
                            endColumnIndex: 3
                        },
                        filterSpecs: [
                            {
                                filterCriteria: {
                                    condition: {
                                        type: 'BLANK',
                                        values: []
                                    }
                                },
                                columnIndex: 1
                            }
                        ]
                    }
                }
            }]
        }
    }

    sheets.spreadsheets.batchUpdate(request).then(res => console.log(res)).catch(err => console.log(err))
}

第 65-80 行(allSheetsData.forEach)用于收集 sheetId 并将它们放入以 sheet 的名称为键的对象中。我将使用此数组循环遍历我想要的 sheets,我将以编程方式将行索引和列索引设置为 sheets 维度。由于我 运行 的错误,我还没有实现这个。如果我更新代码并 运行 回到另一个问题,我会 post.