Связывание данных строк с данными importrange в новой книге в Google Sheets - PullRequest
0 голосов
/ 07 ноября 2018

Для нашей дистрибьюторской компании у нас есть лист, в котором перечислены все счета-фактуры (в обратном хронологическом порядке, чтобы сохранить самые последние счета-фактуры вверху), а также соответствующие данные, которые добавит наш специалист по выставлению счетов / счетов. Дата заказа, название компании, место нахождения, промежуточная сумма счета, налоги, общая сумма, непогашенный остаток, статус доставки и т. Д.

Затем у меня есть другой лист, который извлекает эти данные для нашей команды по выполнению и отправке. Он фильтрует только релевантные столбцы (такие вещи, как промежуточный итог счета / налоги, дата заказа и т. Д. Удаляются). У меня нет фильтра по строкам, поэтому он включает ВСЕ счета из исходного листа.

Я хочу включить в эту таблицу столбец «дата доставки» и столбец «назначенный драйвер», что я и сделал, но, как и большинство людей, пытающихся сделать что-то подобное здесь, когда добавляется новый счет, вручную введенные данные на этом втором листе не смещаются динамически вместе с импортированными данными, что приводит к смещению строк.

Формула для второго листа: =query(IMPORTRANGE("sheet_id","'Order Tracker'!A:T"),"select Col1, Col3, Col5, Col6, Col9, Col10, Col11, Col12, Col19 where Col10 = 'New' OR Col10 = 'Packed' OR Col10 = 'Pending'",1) У меня есть столбцы 10/11 в качестве столбцов ручного ввода для назначения драйвера и даты доставки. К сожалению, как я уже говорил, строки не слипаются друг с другом, так как динамический порядок импортируемых столбцов изменяется, статический порядок столбцов вручную вызывает несоответствие.

Есть ли способ заставить эту работу? Допустим, у меня есть следующие счета-фактуры с датами доставки и драйвером, введенными вручную на этом втором листе:

INV-005 | 10/26 | Frank
INV-004 | 10/27 | Brandon
INV-003 | 10/27 | Frank
INV-002 | 10/26 | Frank
INV-001 | 10/28 | Brandon

А затем я добавляю новый счет-фактуру INV-006 вверху оригинальной таблицы счетов-фактур. Теперь электронная таблица выполнения покажет:

INV-006 | 10/26 | Frank
INV-005 | 10/27 | Brandon
INV-004 | 10/27 | Frank
INV-003 | 10/26 | Frank
INV-002 | 10/28 | Brandon
INV-001

Вместо этого я хочу показать:

INV-006
INV-005 | 10/26 | Frank
INV-004 | 10/27 | Brandon
INV-003 | 10/27 | Frank
INV-002 | 10/26 | Frank
INV-001 | 10/28 | Brandon

1 Ответ

0 голосов
/ 19 ноября 2018

Сценарий ниже будет делать то, что вам нужно.

Когда вы вносите изменения в лист заказа, лист доставки будет обновляться правильно. Будет обновлено:

  1. При открытии накладной
  2. Если вы нажмете кнопку REFRESH на листе поставки.

(поэтому не так автоматически, как при использовании формулы "query(IMPORTRANGE..)").

Вот код, который вам нужно будет установить.

function onOpen() {
   updateTracker();
}


function updateTracker(){
  // This function is executed when the sheet is opened
  // and also intended to be linked to a REFRESH button to be installed in the sheet
  // The function populates ColA to ColK with data from another sheet
  // Existing data in ColL and ColM has to be preserved, and realigned 
  // with the same invoice numbers in ColA of the new data.

  // Step 1 - read ColA, ColL and ColM of the old data, before repopulating ColA and ColsK
  //---------------------------------------------------------------------------------------
  //var openSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Open Order Tracker");
  var openSheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  var lastRow = openSheet.getLastRow(); // locate last row of data
  var invNoArray = openSheet.getRange(2,1,lastRow-1).getValues();   // 1D array of invoices numbers
  var invNoList = {}; 
  for(var row=0; row < invNoArray.length; row++){  // make an "associative array" of invoice numbers
     invNoList[invNoArray[row]] = row;
  }
  // read the delivery dates and driver from this sheet ('Open Order Tracker')
  var driverArray = openSheet.getRange(2,12,lastRow-1,3).getValues();  // 2D array of Delivery Dates and Drivers
  // clear out the old content (not formats or vaidation)
  var currentRange = openSheet.getRange(2,1,lastRow,14); 
  currentRange.clearContent();    

  // Step 2 - Read and the data for ColA to ColK from the source sheet
  //------------------------------------------------------------------
  // Simulating this formula
  //=query(IMPORTRANGE("1rm31Zza8fMS2pASIuFvQ0WBBqWb-174lD5VrtAixDjg","'Order Tracker'!A:T"),"select Col1, Col2, Col3, Col5, Col9, Col10, Col11, Col12, Col13, Col14, 
  // Col19 where Col10 = 'New' OR Col10 = 'Packed' OR Col10 = 'Pending' OR(Col10 = 'Delivered' AND Col14 > 0.01)",1)

  var sourceSheet = SpreadsheetApp.openById('1LU-dSlGqyiKj6xjo5AVvNNdf1pBR26NTuaXZBdLK2Og').getSheetByName("Order Tracker");
  var dataRange = sourceSheet.getDataRange();
  var dataValues = dataRange.getValues().filter(function (x) {return x[9]=='New' || x[9] =='Packed' || x[9] == 'Pending' || (x[9] == 'Delivered' && x[13] >=0.01);});

  // Remove columns we dont need.
  var reqValues = [];
  var reqCols=[0,1,2,4,8,9,10,11,12,13,18];    // corresponding to Col1, Col2 etc
  for(var row=0; row<dataValues.length; row++){
    var thisRow = [];
    for (var col=0; col<reqCols.length; col++){
      thisRow.push(dataValues[row][reqCols[col]]);
    }
    // Add placeholders cols for ColL and ColM
    thisRow.push("None");
    thisRow.push("None");
    thisRow.push("None");   // to be removed later
    reqValues.push(thisRow);
  }

  // Step 3 - Populate ColL and ColM - re-aligning the Invoice Numbers
  //------------------------------------------------------------------
  for (var row=0; row < reqValues.length; row++){
    if (invNoList.hasOwnProperty(reqValues[row][0])){
       var invNoIndex= invNoList[reqValues[row][0]];      // locate correct data based on invoice number
       reqValues[row][11] = driverArray[invNoIndex][0];   // fill in Delivery Date
       reqValues[row][12] = driverArray[invNoIndex][1];   // fill in the Driver
       // below line to be removed later
       reqValues[row][13] = driverArray[invNoIndex][2];   // fill in the CrossCheck data
    }  
  }

  //Step 4 -  Copy the reqValues
  //-----------------------------------------------
  var finalRange = openSheet.getRange(2,1,reqValues.length,14);   // openSheet and lastRow should be still valid
  finalRange.setValues(reqValues);

  //Done
}

Я проверил это в копиях ваших тестовых листов, и все, кажется, работает хорошо. Эта ссылка является версией вашего листа выполнения и содержит сценарий и кнопку «Обновить», установленные в полковнике М: https://docs.google.com/spreadsheets/d/15ecr9CmXn2YyhMpGTg8VCVf8tTi5GaGrjgmQus9FxWA/edit?usp=sharing

ПРИМЕЧАНИЕ для любых экспертов по сценариям Google: Мне пришлось сделать версию сценария оригинальной формулы "query(IMPORTRANGE..)". Это на шаге 2. Если кто-нибудь видит лучший способ сделать это, мне было бы интересно услышать. Я сделал это из-за ограничений скрипта Google (насколько я понимаю):

  1. Нет события после выполнения "query(IMPORTRANGE..)"
  2. Если я устанавливаю запрос в сценарии, его невозможно выполнить в сценарии.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...