當前的問題:
大家好,感謝這里的任何幫助,因為我仍在開始我的編碼之旅。
我想看看我是否可以制作一個腳本:
- 查找重復項(在 D 列中),以及
- 在列 EL 中的第一次匹配之后從以下重復項中洗掉任何資料(如果這在口頭上沒有意義,請參閱所需的結果)。
- 該腳本需要使用列標題名稱(例如“小吃”)而不是硬編碼的列參考
*因此,例如,腳本查找 ABC001,僅洗掉相應列中 ABC001 的重復項,然后移至 ABC004 并執行相同的操作。
我不確定如何撰寫一個可以執行此操作的腳本,并在找到第一組后繼續查找重復項。我想我現在知道如何進行 for 回圈了,但我不清楚如何讓它進行搜索回圈并在找到第一個匹配項后停止并繼續前進。
當前資料:

期望的結果:

代碼到目前為止。我想我需要加入像這個例子中展示的 JSmith 之類的東西?或者我是否需要.length在for陳述句中包含某種形式的重復范圍,以便它可以找到重復項,獲取它們的#,然后只對第一個實體之后的所有內容執行操作?
function duplicateRemoval() {
ss = SpreadsheetApp.getActive().getSheetByName('Sheet1');//gets sheet by name
const [aB,...cd] = ss.getDataRange().getValues();//literal assignment that assigns aB to the header array and the rest of the data to 'cd'
let column = {}
let iData = {};//index into the row array for each column header
aB.forEach((a,i)=>{column[a] = i 1;iData[a]=i});//building column and iData so that headers can move anywhere
}
原始資料:
| 姓名 | 所有者 | 小吃 | 交易 # | 要求的零食數量 | #2 | #3 | #4 | #5 | #6 | #7 | #8 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 賬單示例 | 小吃城 | 芹菜 | ABC001 | 4 | 1 | 2 | 3 | 4 | 5 | 6 | 4 |
| 賬單示例 | 小吃城 | 芹菜 | ABC001 | 4 | 1 | 2 | 3 | 4 | 5 | 6 | 4 |
| 賬單示例 | 小吃城 | 芹菜 | ABC001 | 4 | 1 | 2 | 3 | 4 | 5 | 6 | 4 |
| 簡·多伊 | 小吃城 | 籌碼 | ABC002 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
| 簡·多伊 | 芯片世界 | 籌碼 | ABC003 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
| 簡·多伊 | 芯片世界 | 籌碼 | ABC004 | 5 | 5 | 1 | 1 | 1 | 1 | 1 | 5 |
| 簡·多伊 | 芯片世界 | 籌碼 | ABC004 | 5 | 5 | 1 | 1 | 1 | 1 | 1 | 5 |
| 簡·多伊 | 芯片世界 | 籌碼 | ABC004 | 5 | 5 | 1 | 1 | 1 | 1 | 1 | 5 |
| 簡·多伊 | 芯片世界 | 籌碼 | ABC004 | 5 | 5 | 1 | 1 | 1 | 1 | 1 | 5 |
資料來源:
谷歌應用程式腳本陣列從頂部洗掉重復值
Google Script App 在 Google Sheet 的特定列中洗掉具有特定值的重復行
如何在保留 Google 表格中第一次出現的重復值的同時查找和洗掉一系列單元格中的重復值?
uj5u.com熱心網友回復:
假設事務 id 總是分組的,遍歷行并洗掉所有指定的列,其中先前的 transactionId 等于當前的 transactionId。
function duplicateRemovalOfColsToRemove() {
const transactionsHeader = 'Transaction #',
colsToRemoveHeaders = ['# of snacks requested', '#2'],//add column headers as necessary
ss = SpreadsheetApp.getActive().getSheetByName('Sheet1'), //gets sheet by name
range = ss.getDataRange(),
[headers, ...values] = range.getValues(),
colsToRemove = colsToRemoveHeaders.map((h) => headers.indexOf(h)),
transactionsIdx = headers.indexOf(transactionsHeader);
let currTransaction = '';
values.forEach((row) =>
row[transactionsIdx] === currTransaction
? colsToRemove.forEach((idx) => (row[idx] = ''))
: (currTransaction = row[transactionsIdx])
);
range.setValues([headers, ...values]);
}
uj5u.com熱心網友回復:
目前還不清楚為什么要在此處使用腳本,因為這對于普通的電子表格公式似乎是可行的。還不清楚您是否真的需要A2:D多次重復這些值而列中沒有任何內容E2:L。
要洗掉重復行,并僅獲取每個唯一交易的一份副本,請選擇“插入”>“作業表”并將此電子表格公式放入單元格中A1:
=unique(Sheet1!A2:L)
要獲得您顯示的預期結果,包括大部分為空白的行,請使用以下命令:
=arrayformula(
{
Sheet1!A2:D,
array_constrain(
if(
Sheet1!D2:D <> Sheet1!D1:D,
Sheet1!E2:L,
iferror(1/0)
),
rows(Sheet1!E2:L), columns(Sheet1!E2:L)
)
}
)
要根據所有列A2:D而不是僅根據 column 中的事務 ID確定行唯一性D2:D,請將if()條件替換為A2:A & B2:B & C2:C & D2:D <> A1:A & B1:B & C1:C & D1:D,插入正確的作業表參考。
uj5u.com熱心網友回復:
如果你需要一個腳本,你可以試試這個:
function main() {
var ss = SpreadsheetApp.getActiveSpreadsheet()
var sheet = ss.getActiveSheet();
var range = sheet.getDataRange();
// get all data from the sheet
var data = range.getValues();
// get column headers
var headers = data.shift();
// get the list of transactions
var transactions = data.map(x => x[headers.indexOf('Transaction #')]);
// loop through all the transactions
for (let transaction of transactions) {
// get indexes of rows to process
var rows = transactions.map((t, row) => t === transaction ? row : '' ).filter(String).slice(1);
// process the rows
for (let r of rows) {
data[r][headers.indexOf('# of snacks requested')] = '';
data[r][headers.indexOf('#2')] = '';
data[r][headers.indexOf('#3')] = '';
data[r][headers.indexOf('#4')] = '';
data[r][headers.indexOf('#5')] = '';
data[r][headers.indexOf('#6')] = '';
data[r][headers.indexOf('#7')] = '';
data[r][headers.indexOf('#8')] = '';
}
}
// put the updated data back to the sheet
range.setValues([headers, ...data]);
}
更新
這是相同代碼的改進變體。它仍然遍歷所有行,但會跳過已處理的事務:
function main() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var range = sheet.getDataRange();
var [headers, ...data] = range.getValues();
var transactions = data.map(x => x[headers.indexOf('Transaction #')]);
var cols_to_clean = ['# of snacks requested','#2','#3','#4','#5','#6','#7','#8'];
var processed_transactions = [];
for (let transaction of transactions) {
// skip already processed transactions
if (processed_transactions.includes(transaction)) continue;
var rows_to_clean = transactions.map((t, row) => t === transaction ? row : '' )
.filter(String).slice(1);
for (let r of rows_to_clean) {
cols_to_clean.forEach(c => data[r][headers.indexOf(c)] = '');
}
processed_transactions.push(transaction);
}
range.setValues([headers, ...data]);
}
感謝@TheMaster 指出的不足。
更新 2
對不起,垃圾郵件,只是想出了沒有冗余迭代的最終解決方案(我希望):
function main() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var range = sheet.getDataRange();
var [headers, ...data] = range.getValues();
var cols_to_clean = ['# of snacks requested','#2','#3','#4','#5','#6','#7','#8'];
// get all transactions (9 items for this data)
var all_transactions = data.map(x => x[headers.indexOf('Transaction #')]);
// get the short list of unique transaction (4 items for this data)
var uniq_transactions = [... new Set(all_transactions)];
for (let transaction of uniq_transactions) {
// get all indexes of rows with given transaction
var rows_to_clean = all_transactions.map((t, row) => t === transaction ? row : '')
.filter(String).slice(1);
// clean the rows
for (let r of rows_to_clean) {
cols_to_clean.forEach(c => data[r][headers.indexOf(c)] = '');
}
}
range.setValues([headers, ...data]);
}
我沒有洗掉我的第一個更新,我認為這對教育目的很有用。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/374833.html
標籤:谷歌应用程序脚本
