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.
通过 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.