我正在尝试使列中以竖线分隔的单元格值唯一
示例
如果D3的单元格值= Aa Bb | HH | Aa Bb | HH
然后在运行arrMakeUnique_n()之后,D3的单元格值= Aa Bb | HH
这是可行的,但是如果D2的单元格值与D3相同,则仅使D3的单元格值唯一D2不变
即
如果有多个具有相同值的单元格,则只有一个单元格是唯一的,其他单元格保持不变
我不明白为什么,需要任何帮助
谢谢
function arrMakeUnique_n() {
arrMakeUnique(
'sheet1',
["Header"],
"|",
"|"
);
}
function arrMakeUnique(shtName,cheaders, dilm1, dilm2) {
var sheet = SpreadsheetApp.getActive().getSheetByName(shtName);
var range = sheet.getDataRange();
var rangeValues = range.getValues();
var LR = sheet.getLastRow();
var hn =[];
var fhn = [];
for (var k = 0; k <= cheaders.length-1; k++) {
//Get column indexes from headers
hn[k] = HTN(shtName,cheaders[k]) - 1;
}
for (var j = 0; j <= cheaders.length-1; j++) {
var frRange = sheet.getRange(2, hn[j]+1, LR-1, 1);
var frValues = frRange.getValues();
// iterate through all cells in the selected range
for (var cellRow = 1; cellRow < LR; cellRow++) {
//Make array with split on | get unique with .getUnique() then Join with |
//Logger.log((rangeValues[cellRow][hn[j]].toString().split(frValues[cellRow]+dilm1)).getUnique().join(frValues[cellRow]+dilm2).trim())
rangeValues[cellRow][hn[j]] = (rangeValues[cellRow][hn[j]].toString().split(frValues[cellRow]+dilm1)).getUnique().join(frValues[cellRow]+dilm2).trim();
}
}
// Write back all values at once
range.setValues(rangeValues);
}
编辑:事实证明,使用:.getUnique
会导致奇怪的行为,因为它干扰了其他与使用无关的脚本。 xyz解决方案非常幸运
//Make array unique
Array.prototype.getUnique = function(){
var u = {}, a = [];
for(var i = 0, l = this.length; i < l; ++i){
if(u.hasOwnProperty(this[i])) {
continue;
}
a.push(this[i]);
u[this[i]] = 1;
}
return a;
}
function HTN(shtName,cheader){
var headers = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(shtName).getDataRange().getValues().shift();
var colindex = headers.indexOf(cheader);
return colindex+1;
}
答案 0 :(得分:3)
您真的需要编写脚本吗?以下使用本机google-spreadsheet函数的公式可以正常工作。
=join("|", unique(transpose(split(D3, "|", false, true))))
也许插入列,向下运行该公式然后将结果还原为值并删除原始列(无论是否使用脚本)会更容易。
答案 1 :(得分:3)
使用数组合并功能(对于其他用例,您也会发现它非常有用):
function deDupe(){
var spread = SpreadsheetApp.getActiveSpreadsheet();
var sheet = spread.getActiveSheet();
sheet.getRange("D3").setValue(merge(sheet.getRange("D3").getValue().split("|")));
//In your scenario only D3 is modified, but I think you forgot to ask, if D3 and D2 are different AFTER the code runs, then set them equal.
if (sheet.getRange("D3").getValue()!=sheet.getRange("D2").getValue()){
sheet.getRange("D2").setValue(sheet.getRange("D3").getValue());
//Or do something different
}
}
function merge(a1, a2) {
var hash = {};
var arr = [];
var target = "";
for (var i = 0; i < a1.length; i++) {
if (hash[a1[i]] !== true) {
target = a1[i].trim();
if (target.length>0) {
hash[target] = true;
arr[arr.length] = target;
}
}
}
if (arguments.length == 2) {
for (var i = 0; i < a2.length; i++) {
if (hash[a2[i]] !== true) {
target = a2[i].trim();
if (target.length>0) {
hash[target] = true;
arr[arr.length] = target;
}
}
}
}
return arr;
}
请注意,我只传递了一个要合并的数组。如果您两次传递相同的数组,它实际上的工作原理相同,但是显然会花费更多时间。
答案 2 :(得分:3)
更改此
rangeValues[cellRow][hn[j]] = (rangeValues[cellRow][hn[j]].toString().split(frValues[cellRow]+dilm1)).getUnique().join(frValues[cellRow]+dilm2).trim();
对此
rangeValues[cellRow][hn[j]] = rangeValues[cellRow][hn[j]].toString().split(dilm1).getUnique().join(dilm2).trim();
此外,如果您要对单元格值进行排序
//Make array unique
Array.prototype.getUnique = function(){
var u = {}, arr = [];
for(var i = 0, l = this.length; i < l; ++i){
if(u.hasOwnProperty(this[i])) {
continue;
}
arr.push(this[i]);
u[this[i]] = 1;
}
arr.sort(lowerCase);
function lowerCase(a,b){
return a.toLowerCase()>b.toLowerCase() ? 1 : -1;// sort function that does not "see" letter case
}
return arr;
}
答案 3 :(得分:2)
这是另一种方法:
function removeDuplicateFromDilmStr_n() {
var t="Abb Baa|HHH|Abb Baa"
Logger.log(removeDuplicateFromDilmStr(t,"|", "|"))
}
function removeDuplicateFromDilmStr(str, dilm1, dilm2){
var arr = str.toString().split(dilm1)
var outArray = [];
arr.sort(lowerCase);
function lowerCase(a,b){
return a.toLowerCase()>b.toLowerCase() ? 1 : -1;// sort function that does not "see" letter case
}
var unique_array = arr.filter(function(elem, index, self) {
return index == self.indexOf(elem);
});
unique_array = unique_array.join(dilm2).trim();
return unique_array
}
然后更改此:
rangeValues[cellRow][hn[j]] = (rangeValues[cellRow][hn[j]].toString().split(frValues[cellRow]+dilm1)).getUnique().join(frValues[cellRow]+dilm2).trim();
对此:
rangeValues[cellRow][hn[j]] = removeDuplicateFromDilmStr(rangeValues[cellRow][hn[j]], "|","|");