Я пытаюсь загрузить диапазон данных в Salesforce, используя следующий скрипт, однако в настоящее время он настроен на выполнение только одной строки за раз, что я использую в цикле for в другой функции, однако мои данные часто превышают 2000 строк и я перестал Я использую функцию для форматирования диапазона данных в формате JSON. Можно ли вставить каждый JSON в массив и передать его через мой HTTP-вызов за один раз?

Загрузить в SF

function upsert(object, pl, id, idField, row) {
  var payload = tableJSON(pl);
  var sfService = getSfService();
  var userProps = PropertiesService.getUserProperties();
  var props = userProps.getProperties();
  var name = getSfService().serviceName_;
  var obj = JSON.parse(props['oauth2.' + name]);
  var instanceUrl = obj.instance_url;
  var queryUrl = instanceUrl + "/services/data/v42.0/sobjects/" + object +"/" + idField +"/" + id;
  var response = UrlFetchApp.fetch(queryUrl, {
    headers: {
      Authorization: "Bearer " + sfService.getAccessToken()
    },
    contentType: 'application/json',
    payload: payload,
    method: "PATCH",
    muteHttpExceptions: true
  });
}

TableJSON

function tableJSON(arr) {
  var i, j, obj = {};
  for (i = 0; i < arr.length; i++) {
    for (j = 0; j < arr[0].length; j++) {
      obj[arr[0][j]] = arr[i][j];
    }
  }
  return JSON.stringify(obj);
}

Если кто-то знаком с этим, я пытаюсь воссоздать то, что делает надстройка Data Connector от Google.

Опять же, я хочу взять диапазон данных, преобразовать его в полезную нагрузку, которую я могу запустить через HTTP-вызов, и предпочтительно обновить каждую строку с успехом или кодом ответа / телом ошибки. У меня вопрос, как мне отформатировать полезную нагрузку, чтобы сделать эту работу, как описано?

Редактировать: я не включил все функции, такие как getSfService (). Если вы хотите увидеть все это, здесь есть github, с которым я работал для создания своего кода.

Редактировать: это то, что в конечном итоге работал для меня:

function upsertPage(object, idCol) {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = ss.getActiveSheet();
  var data = sheet.getDataRange().getDisplayValues();
  var sfService = getSfService();
  var userProps = PropertiesService.getUserProperties();
  var props = userProps.getProperties();
  var name = getSfService().serviceName_;
  var obj = JSON.parse(props['oauth2.' + name]);
  var instanceUrl = obj.instance_url;
  var idCol = colCt(idCol);
  var idField = data[0][idCol];
  var dataJSON = getJSON(data,idCol);
  var requestArr = [];
  for (i=1;i<data.length;i++){
    var id = data[i][idCol];
    var payload = JSON.stringify(dataJSON[i-1]);
    var request = {
      'url': instanceUrl + "/services/data/v42.0/sobjects/" + object +"/" + idField +"/" + id,
      'headers': {Authorization: "Bearer " + sfService.getAccessToken()},
      'contentType': 'application/json',
      'method': 'PATCH',
      'payload': payload,
      'muteHttpExceptions': true
      };    
    requestArr.push(request);
  };
var response = UrlFetchApp.fetchAll(requestArr);
  }
}

function colCt(colLetter){
  var abc = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'];
  for (i=0;i<abc.length;i++){
    var colLetter = colLetter.toUpperCase();
    if (colLetter === abc[i].toUpperCase()){
      return i;
      }
    }
  }

  function getJSON(data, extIdCol){
  var obj = {};
  var result = [];
  var headers = data[0];
  var cols = headers.length;
  var row = [];
  var extIdHeader = data[0][extIdCol];

  for (var i = 1, l = data.length; i < l; i++){
    // get a row to fill the object
    row = data[i];
    // clear object
    obj = {};
    for (var col = 0; col < cols; col++) 
    {
      // fill object with new values
      obj[headers[col]] = row[col];    
    }
    // add object in a final result
    result.push(obj);  
  }
  for(i=0;i<result.length;i++){
    delete result[i][extIdHeader];
    }
  return result;  
}
1
NMALM 29 Фев 2020 в 02:18

2 ответа

Лучший ответ

У меня нет опыта работы со скриптами в Google Apps, но я могу помочь с битом SF. У вас есть список объектов JSON, которые, как мы надеемся, содержат действительный идентификатор записи SF, и вы хотите их массовое обновление?

Возможно, вам придется поэкспериментировать с Postman, SoapUI и т. Д. С правильным запросом. Или Workbench - достойный вариант (экономит вам шаг при входе в систему). В REST API Salesforce есть метод массового обновления нескольких объектов по идентификатору. Они даже не обязательно должны быть в одной таблице (представьте, что нужно обновить учетную запись, контакты, возможности в 1 запросе и при любой ошибке - откатить все 3, интересно!). Начните с https: //developer.salesforce. ком / документы / atlas.en - us.api_rest.meta / api_rest / resources_composite_sobjects_collections_update.htm

Если у вас нет идентификаторов записей SF, но ваш сценарий - «Уважаемые продавцы», мне все равно, какой у вас уникальный идентификатор. В моей системе это 12345, я даже не помню, отправил ли я вам это сделайте запись раньше, сами разберитесь с беспорядком, вот новое состояние для сохранения, вы поймете, нужно ли вставлять или обновлять "... Это называется операцией переноса, это выполнимо, если вы делаете некоторые приготовления (создайте поле, помеченное как «Внешний идентификатор» в первую очередь). Но это не очень хорошо подходит для массовых рассылок, вам нужно быть немного креативным, как мой ответ здесь: https://salesforce.stackexchange.com/questions/274694/can-you-upsert-using-composite-sobject-tree

Насколько я помню, они имеют ограничение максимум 200 «строк» на запрос, и вы можете указать, хотите ли вы «откатить всю транзакцию» или «сохранить то, что вы можете». Оба эти примера являются синхронными (вы отправляете и ждете результатов). Если у вас все еще есть узкие места в производительности, вы можете захотеть заглянуть в асинхронный REST API, где вы отправляете задание, периодически вызываете «это уже сделано», а затем вы можете загрузить файл, сопоставить его с исходными строками ... сдвиг архитектуры кода, попробуйте сначала достичь предела 200, прежде чем начинать с преждевременной оптимизации.

1
eyescream 29 Фев 2020 в 22:30

Я думаю, что нашел свой ответ, но все еще надеялся, что кто-то сможет подтвердить.

Если я использую UrlFetchApp.fetchAll и передаю информацию для каждой строки в качестве запроса, я думаю, что я мог бы сделать это в цикле. Это правильно?

0
NMALM 29 Фев 2020 в 00:49