Sheets.Spreadsheets.BatchUpdate가있는 잘못된 JSON 페이로드

Oct 05 2020

Sheets.Spreadsheets.Get 및 Sheets.Spreadsheets.Batchupdate로 작업하려고합니다. 한 스프레드 시트에서 서식을 가져 와서 다른 스프레드 시트에 붙여 넣으려고합니다. 이것은 단순히 추가 적용을위한 개념 증명입니다. 다음 코드에서 JSON 페이로드 오류가 발생하고 배열을 삽입하기 위해 형식을 지정하는 방법을 알 수 없습니다.


function Test() {
 //sheets[].data[].rowData[].values[].cellData.effectiveFormat.backgroundColor
 var TestArray = Sheets.Spreadsheets.get("1eAq-RbtrCSMRPZ0p7XIpG3vd29yL-3SQ3D3JGyiUhKg", {
   ranges:"Awesome!A1:C3",
   fields:"sheets(data(rowData(values(effectiveFormat.backgroundColor))))"
 });
 
var spreadsheetId = "1eAq-RbtrCSMRPZ0p7XIpG3vd29yL-3SQ3D3JGyiUhKg";
 var result = Sheets.Spreadsheets.batchUpdate({
   requests: [{
     updateCells: {
       rows: [{
         values: [{
           userEnteredValue: {
             stringValue: 'Test String'
           }, userEnteredFormat: {
               backgroundColor: TestArray
             }
         }]
       }],//rows
       fields: 'userEnteredValue.stringValue,userEnteredFormat.backgroundColor',
       start: {
         sheetId: 1616717220,
         rowIndex: 0,
         columnIndex: 0
       }
     }//update cell
   }]//requests
 }, spreadsheetId)
}  ```

**EDIT:**

Rebuilt function copying both Text and Background colors. 

function myFunction() {

var TestArray = Sheets.Spreadsheets.get("1eAq-RbtrCSMRPZ0p7XIpG3vd29yL-3SQ3D3JGyiUhKg", {
   ranges:"Awesome!A1:C3",
   fields:"sheets(data(rowData(values(effectiveFormat.backgroundColor))))"
 });
 
 var backgroundColors = TestArray["sheets"][0]["data"][0]["rowData"]
                      .map(row => row["values"]
                      .map(value => value["effectiveFormat"]["backgroundColor"]));
 
 var TotalText = Sheets.Spreadsheets.Values.get("1eAq-RbtrCSMRPZ0p7XIpG3vd29yL-3SQ3D3JGyiUhKg", "Awesome!A1:C3").values; 
 
//Map Text
var textrows = TotalText.map(rowText => {
 return {
   values: rowText.map(cellText => {
     return {
       userEnteredValue: {
         stringValue: cellText         
       }
     }       
   })
 }
})

//Map Background Colors
var colorrows = backgroundColors.map(rowColors => {
 return {
   values: rowColors.map(cellColor => {
     return {
       userEnteredFormat: {
         backgroundColor: cellColor        
       }       
     }             
   })
 }
})

var spreadsheetId = "1eAq-RbtrCSMRPZ0p7XIpG3vd29yL-3SQ3D3JGyiUhKg";
var result = Sheets.Spreadsheets.batchUpdate({
  requests: [{
    updateCells: {
      rows: textrows,
      fields: 'userEnteredValue.stringValue',
      start: {
        sheetId: 1616717220,
        rowIndex: 0,
        columnIndex: 0
      }
    }//update cell
  },{
    updateCells: {
      rows: colorrows,
      fields: 'userEnteredFormat.backgroundColor',
      start: {
        sheetId: 1616717220,
        rowIndex: 0,
        columnIndex: 0
      }
    }
  }]
}, spreadsheetId)
}


Edit #2:

   function myFunctionOneRequest() {


var TestArray = Sheets.Spreadsheets.get("1eAq-RbtrCSMRPZ0p7XIpG3vd29yL-3SQ3D3JGyiUhKg", {
   ranges:"Awesome!A1:C3",
   fields:"sheets(data(rowData(values(effectiveFormat.backgroundColor))))"
 });
 
 var backgroundColors = TestArray["sheets"][0]["data"][0]["rowData"]
                      .map(row => row["values"]
                      .map(value => value["effectiveFormat"]["backgroundColor"]));
 
 var TotalText = Sheets.Spreadsheets.Values.get("1eAq-RbtrCSMRPZ0p7XIpG3vd29yL-3SQ3D3JGyiUhKg", "Awesome!A1:C3").values; 

 
//Map Text
var textrows = TotalText.map((rowText,i) => {
 return {
   values: rowText.map((cellText,j) => {
     return {
       userEnteredValue: {
         stringValue: cellText         
       }
     }       
   })
 }
})

//Map Background Colors
var colorrows = backgroundColors.map((rowColors,k) => {
 return {
   values: rowColors.map((cellColor,l) => {
     return {
       userEnteredFormat: {
         backgroundColor: cellColor        
       }       
     }             
   })
 }
})

var spreadsheetId = "1eAq-RbtrCSMRPZ0p7XIpG3vd29yL-3SQ3D3JGyiUhKg";
var result = Sheets.Spreadsheets.batchUpdate({
  requests: [{
    updateCells: {
      rows: textrows,
      fields: 'userEnteredValue.stringValue',
      start: {
        sheetId: 1616717220,
        rowIndex: 0,
        columnIndex: 0
      }
    }//update cell
  }]
}, spreadsheetId)
}

답변

Iamblichus Oct 05 2020 at 18:02

발행물:

당신은에 공급하고 스프레드 시트 자원 ( TestArray에 의해 반환, spreadsheets.get 당신이 제공해야합니다) 색상을 . 따라서 잘못된 JSON 페이로드 오류가 발생합니다.

이는 fields매개 변수가 첫 번째 호출의 응답으로 채워질 중첩 필드를 필터링하지만 이러한 중첩 필드는 여전히 JSON에 중첩되므로 해당하는 상위 속성을 지정하여 액세스해야하기 때문입니다.

해결책:

첫 번째 호출에 대한 응답은 다음과 같습니다.

{
  "sheets": [
    {
      "data": [
        {
          "rowData": [
            {
              "values": [
                {
                  "effectiveFormat": {
                    "backgroundColor": {
                      "red": 1,
                      "green": 1,
                      "blue": 1
                    }
                  }
                },
                // Other cells in row
              ]
            },
            // Other rows in the requested range
          ]
        } // Only one range is specified, so there's only one GridData element
      ]
    },
    // Other sheets
  ]
}

예를 들어 backgroundColor요청 된 범위에서 첫 번째 행의 첫 번째 셀에 액세스 하려면 다음을 수행해야합니다.

var backgroundColor = TestArray["sheets"][0]["data"][0]["rowData"][0]
                                 ["values"][0]["effectiveFormat"]["backgroundColor"];

또는 backgroundColors요청 된 범위에있는 모든 셀의 2D 배열을 검색하려는 경우 다음을 수행 할 수 있습니다.

var backgroundColors = TestArray["sheets"][0]["data"][0]["rowData"]
                       .map(row => row["values"]
                       .map(value => value["effectiveFormat"]["backgroundColor"]));

여러 셀을 업데이트하려면 그에 따라 요청 본문을 편집하여 추가 rows및 values해당 배열을 추가 해야합니다.

편집하다:

예를 들어 대상 셀의 배경색이 소스와 동일하고 모두 값 Test String이되게하려면 다음과 같이 요청 본문을 빌드 할 수 있습니다.

var rows = backgroundColors.map(rowColors => {
  return {
    values: rowColors.map(cellColor => {
      return {
        userEnteredValue: {
          stringValue: 'Test String'         
        }, 
        userEnteredFormat: {
          backgroundColor: cellColor        
        }       
      }             
    })
  }
})
var result = Sheets.Spreadsheets.batchUpdate({
   requests: [{
     updateCells: {
       rows: rows,
       fields: 'userEnteredValue.stringValue,userEnteredFormat.backgroundColor',
       start: {
         sheetId: 1616717220,
         rowIndex: 0,
         columnIndex: 0
       }
     }//update cell
   }]//requests
}, spreadsheetId)

각 셀에 서로 다른 문자열 값이 있어야하는 경우 2D 배열에 저장 하고 해당 인덱스를 지정하는 map대신 메서드 내부에 제공해야 Test String합니다 (각에 선택적 매개 변수로 제공됨 map).

편집 2 :

같은 요청에 두 값과 배경 색상을 업데이트하려면, 당신은 그들 중 하나를 통해 단지 반복 할 수 map및 (그들은의 선택적 매개 변수입니다 해당 인덱스 매개 변수를 사용하여 map호출 방법 i과 j다른 액세스 아래 샘플) 다른 하나의 가치.

예를 들어 를 빌드하는 데 사용하려는 경우 backgroundColors및 strings2D 배열은 다음 과 같이 rows할 수 있습니다.

var backgroundColors = [["2D array with colors"]];
var strings = [["2D array with strings"]];
var rows = backgroundColors.map((rowColors,i) => {
  return {
    values: rowColors.map((cellColor,j) => {
      return {
        userEnteredValue: {
          stringValue: strings[i][j]       
        }, 
        userEnteredFormat: {
          backgroundColor: cellColor        
        }       
      }             
    });
  }
});