目標
防止腳本將導致錯誤的空白(空)行從源復制到目標。
錯誤詳情:
Google App 腳本:TypeError:無法讀取未定義的屬性“長度”(行 *,檔案“代碼”)
此錯誤指的是以下行:
dstSheet.getRange(dstLastRow 1, 1, values.length, values[0].length).setValues(values);
完整代碼
我正在使用來自HERE的以下代碼,該代碼已稍作修改。無論有沒有修改,都會發生錯誤。代碼的邏輯是:如果目標作業表不包含 ID、匯入 ID 以及從源到目標的特定列。
function importNewEmployeeIds() {
const srcSheetName = 'Source';
const dstSheetName = 'Destination';
const srcSheet = SpreadsheetApp.openById("SpreadsheetID1").getSheetByName(srcSheetName);
const dstSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(dstSheetName);
// Retrieve values from source sheet.
var headerRowNumber = 1;
const srcValues = srcSheet.getDataRange().offset(headerRowNumber, 0, srcSheet.getLastRow() - headerRowNumber).getValues();
// Retrieve values from destination sheet and create an object for searching the ID.
const dstLastRow = dstSheet.getLastRow();
const dstObj = dstLastRow == 0 ? {} : dstSheet.getRange("A1:A" dstLastRow).getValues().reduce((o, [a]) => (o[a] = true, o), {});
// Create an array for putting to the destination sheet.
const values = srcValues.filter(r => !dstObj[r[1]]).map(r => [r[1], r[19], "", r[18]]);
// Put the values to the destination sheet.
dstSheet.getRange(dstLastRow 1, 1, values.length, values[0].length).setValues(values);
}
故障排除
[來源]在腳本運行之前。
| A |B| C | D |
|200001| |Email2|Email1|
|200001| |Email2|Email1|
|200006| |Email4|Email3|
|200007| |Email6|Email5|
| | | | |
[目的地]在腳本運行之前。
| A |B| C | D |
|200001| |Email2|Email1|
[目的地]腳本運行后。
| A |B| C | D |
|200001| |Email2|Email1|
|200006| |Email4|Email3|
|200007| |Email6|Email5|
| | | | | <-- Notice the blank row. I don't want the blank row.
腳本運行后,會將行資料從源復制到目標。問題是,腳本還將空白(空)行復制到源作業表。
[目的地]預期結果- 沒有空白行
| A |B| C | D |
|200001| |Email2|Email1|
|200006| |Email4|Email3|
|200007| |Email6|Email5|
我能想到的菜鳥解決方案:
選項 A)在腳本的開頭,我可以首先從目標中洗掉所有空行。這效率較低,并且不能解決問題的根源,但至少可以解決我的問題。
function removeEmptyRows(){
var sh = SpreadsheetApp.getActiveSheet();
var maxRows = sh.getMaxRows();
var lastRow = sh.getLastRow();
if (maxRows-lastRow != 0){
sh.deleteRows(lastRow 1, maxRows-lastRow);
}
}
找到代碼:這里
選項 B)更新原始代碼,使其不會復制空白行。
[前]
const srcValues = srcSheet.getDataRange().offset(headerRowNumber, 0, srcSheet.getLastRow() - headerRowNumber).getValues();
[后]
const srcValuesAndBlankRows = srcSheet.getDataRange().offset(headerRowNumber, 0, srcSheet.getLastRow() - headerRowNumber).getValues();
const srcValues = srcValuesAndBlankRows.filter(String); //Removes Blank Rows
找到代碼:這里
uj5u.com熱心網友回復:
例如,在您的情況下,如何進行以下修改?我修改了腳本中的 2 個部分。
修改后的腳本:
function Q70718274_importNewEmployeeIds() {
const srcSheetName = 'Source';
const dstSheetName = 'Destination';
const srcSheet = SpreadsheetApp.openById("SpreadsheetID1").getSheetByName(srcSheetName);
const dstSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(dstSheetName);
// Retrieve values from source sheet.
var headerRowNumber = 1;
const srcValues = srcSheet.getDataRange().offset(headerRowNumber, 0, srcSheet.getLastRow() - headerRowNumber).getValues().filter(r => r.join("") != ""); // <--- Modified
// Retrieve values from destination sheet and create an object for searching the ID.
const dstLastRow = dstSheet.getLastRow();
const dstObj = dstLastRow == 0 ? {} : dstSheet.getRange("A1:A" dstLastRow).getValues().reduce((o, [a]) => (o[a] = true, o), {});
// Create an array for putting to the destination sheet.
const values = srcValues.filter(r => !dstObj[r[1]]).map(r => [r[1], r[19], "", r[18]]);
// Put the values to the destination sheet.
if (values.length > 0) { // <--- Added
dstSheet.getRange(dstLastRow 1, 1, values.length, values[0].length).setValues(values);
}
}
- 通過
const srcValues = srcSheet.getDataRange().offset(headerRowNumber, 0, srcSheet.getLastRow() - headerRowNumber).getValues().filter(r => r.join("") != "");,洗掉空行。 - 通過
if (values.length > 0) {},當values沒有值時,不會發生錯誤。
添加:
根據您的以下附加資訊,
[來源]在腳本運行之前。
| A |B| C | D |
|200001| |Email2|Email1|
|200001| |Email2|Email1|
|200006| |Email4|Email3|
|200007| |Email6|Email5|
| | | | |
[目的地]在腳本運行之前。
| A |B| C | D |
|200001| |Email2|Email1|
[目的地]腳本運行后。
| A |B| C | D |
|200001| |Email2|Email1|
|200006| |Email4|Email3|
|200007| |Email6|Email5|
| | | | | <-- Notice the blank row. I don't want the blank row.
腳本運行后,會將行資料從源復制到目標。問題是,腳本還將空白(空)行復制到源作業表。
[目的地]預期結果- 沒有空白行
| A |B| C | D |
|200001| |Email2|Email1|
|200006| |Email4|Email3|
|200007| |Email6|Email5|
我知道您想從前 2 個表中實作底部表。從您提供的腳本中,我認為您想使用const values = srcValues.filter(r => !dstObj[r[1]]).map(r => [r[1], r[19], "", r[18]]);. 但是,從你補充的情況來看,我明白我的理解是不正確的。對于您的其他示例情況,以下腳本怎么樣?
示例腳本:
function importNewEmployeeIds2() {
const srcSheetName = 'Source';
const dstSheetName = 'Destination';
const srcSheet = SpreadsheetApp.openById("SpreadsheetID1").getSheetByName(srcSheetName);
const dstSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(dstSheetName);
// Retrieve values from source sheet.
var headerRowNumber = 1;
const srcValues = srcSheet.getDataRange().offset(headerRowNumber, 0, srcSheet.getLastRow() - headerRowNumber).getValues().filter(r => r.join("") != ""); // <--- Modified
// Retrieve values from destination sheet and create an object for searching the ID.
const dstLastRow = dstSheet.getLastRow();
const dstObj = dstLastRow == 0 ? {} : dstSheet.getRange("A1:A" dstLastRow).getValues().reduce((o, [a]) => (o[a] = true, o), {});
// Create an array for putting to the destination sheet.
// const values = srcValues.filter(r => !dstObj[r[1]]).map(r => [r[1], r[19], "", r[18]]);
const values = srcValues.filter(r => !dstObj[r[0]]).map(r => [r[0], "", r[2], r[3]]); // <--- Modified
// Put the values to the destination sheet.
if (values.length > 0) { // <--- Added
dstSheet.getRange(dstLastRow 1, 1, values.length, values[0].length).setValues(values);
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/411502.html
標籤:
