提问人:workflowz 提问时间:11/17/2023 最后编辑:Tanaikeworkflowz 更新时间:11/18/2023 访问量:47
将包含特定文本的行移动到数组中的最后一行
Moving a row that contains certain text up to the last row in an array
问:
我在这里搜索并尝试修改一些脚本,但没有任何运气。
在我的工作表中,有一个查询引入生产数据。在该数据下方,我有一个浮动的 Grand Totals 行,该行将上述数据的 SKU 计数、总数量和成本相加。我们通常在确认所有生产线项目后,将此行向上拖动到最后一行的下方。
我想在 A 列中搜索包含文本“总计”的行,并将该行及其公式和格式移动到生产数据的最后一行下方。这应该从A6-A499行开始对活动工作表完成。我不想从命名的工作表中获取范围,因为工作表名称是动态的,其中有生产计划的周数。
多年来一直在使用 SO,但这是我的第一篇文章。如果这是重复,请原谅我。我搜索了很多线程,但无法完成此脚本。
这是我一起破解的脚本 - 我觉得 if 语句缺少一些东西..但它可能不止于此。
如果下面的方向和脚本还不够,我可以用谨慎的数据制作一个共享表,但我希望我已经很好地解释了我的需求。
我添加了一个 UI 菜单项来运行它,认为在运行它时我需要在“活动工作表”上,以便也避免需要定义某个工作表名称。我可以看到它在工作簿中的所有工作表上也很有用,在编辑或其他东西时触发。任何建议将不胜感激!
function onOpen() {
SpreadsheetApp.getUi().createMenu("⚙️ Admin Settings")
.addItem("Move GT", "MoveGT")
.addToUi();
}
function MoveGT() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = ss.getActiveSheet();
var r = s.getRange("A6:A499");
if(r.getColumn() == 1 && r.getValue() == "Grand Total") {
var row = r.getRow();
var numColumns = s.getLastColumn();
var targetSheet = ss.getActiveSheet();
var target = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
s.getRange(row, 1, 1, numColumns).moveTo(target);
s.deleteRow(row);
}
}
答:
0赞
Tanaike
11/17/2023
#1
我相信你的目标如下。
- 您想从“A”列中搜索“总计”值。
- 您希望将搜索到的行移动到同一工作表的最后一行,同时保留单元格格式和公式。
- 您希望将搜索的行移动到 A6:L499 范围内的最后一行非空白行。
在您的显示脚本中,当单元格“A6”的值为“总计”时,我认为您的脚本有效。但是,我担心当“总计”放在除“A6”之外的单元格中时,您的脚本无法使用。我猜这可能是您当前的问题。如果我的理解是正确的,那么下面的修改怎么样?
修改后的脚本:
function MoveGT() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = ss.getActiveSheet();
var r = s.getRange("A6:A499");
// I modified the below script.
var lastCol = s.getLastColumn();
var ranges = r.createTextFinder("Grand Total").matchEntireCell(true).findAll().map(e => e.offset(0, 0, 1, lastCol));
if (ranges.length == 0) return;
var lastRow = r.getDisplayValues().findIndex(([a]) => a == "") + r.getRow();
ranges.forEach((e, i) => e.moveTo(s.getRange(lastRow + i, 1)));
ranges.reverse().forEach(e => s.deleteRow(e.getRow()));
}
运行此脚本时,将从“A”列中搜索值“总计”。并且,搜索到的行将移动到同一工作表的最后一行。
我认为在这种情况下,可以使用以下修改后的脚本。
function MoveGT() { var ss = SpreadsheetApp.getActiveSpreadsheet(); var s = ss.getActiveSheet(); var r = s.getRange("A6:A499"); // I modified the below script. var offset = r.getRow(); var values = r.getDisplayValues(); var rows = values.reduce((ar, [a], i) => { if (a == "Grand Total") { ar.push(i + offset); } return ar; }, []); var len = rows.length; if (len == 0) return; var lastRow = values.findIndex(([a]) => a == "") + offset; var lastCol = s.getLastColumn(); rows.forEach((e, i) => s.getRange(e, 1, 1, lastCol).moveTo(s.getRange(lastRow + i, 1))); rows.reverse().forEach(e => s.deleteRow(e)); }
引用:
评论
0赞
workflowz
11/18/2023
非常接近!脚本将其推送到工作表的最后一行。抱歉,我忘了提到我在移动行时要求,它必须搜索 A6:L499 范围内的最后一行非空白行。这是窗口数据在该范围内没有任何公式。列 M-Q 的公式级联到工作表的最后一行,这可能是脚本选择最后一行的原因。在 A500:L600 中,我在另一个脚本中使用了一个隐藏查询。虽然我想移动整个“总计”行,但我需要确定最后一行,其中包含 A6:L499 中的数据并将其移动到该行下方。
0赞
workflowz
11/18/2023
做到了。非常感谢Tanaike的帮助!这将极大地帮助我们的新流程。
0赞
Tanaike
11/18/2023
@workflowz 感谢您再次回复和测试。我很高兴您的问题得到了解决。也谢谢你。
评论
r.getColumn()
r.getValue()
r = s.getDataRange()
r.getLastRow()