我有一个很小的销售团队(有5个人,但正在增长),可以将销售记录到工作簿中的多个工作表中,我想运行一个脚本以将所有这些工作表(如果可能的话)与一个脚本合并。
因此阶段将是每天
1)从每日主数据中删除所有记录(这是为了解释各个销售单中先前数据的任何更改) 2)循环浏览所有工作表并添加数据
共有17列,它们的顺序相同但包含不同的数据。
我尝试使用/编辑/转换以下脚本无济于事,我不确定在indexof('Project')猜测它是布尔值语句后,> -1是什么意思?
我确实尝试将Project添加到我的每个团队工作表中,结果是在Master工作表中只返回了一个工作表。
代码尝试:
function merge() {
var v, arr,
ss = SpreadsheetApp.getActive();
ss.getSheets().filter(function(s) {
return s.getName()
.indexOf('Project') > -1
}).forEach(function(s, i) {
v = s.getDataRange()
.getValues()
.filter(function(r) {
return r.toString()
.length > 0
})
arr = (i == 0) ? v : arr.concat(v);
})
ss.getSheetByName('Master')
.getRange(1, 1, arr.length, arr[0].length)
.setValues(arr);
}
任何帮助将不胜感激。
谢谢!
答案 0 :(得分:1)
尝试使用SheetGo插件,只需单击几下即可完成工作
看看这个: https://blog.sheetgo.com/how-to-solve-with-sheetgo/merge-data-multiple-google-sheets/
答案 1 :(得分:1)
这些是主要功能。
dailysheets.gs:
IFormFile
这些文件只是我经常使用的一些支持文件,在本项目中我使用了其中的一些内容。
triggers.gs:
public class XmlFileAddViewModel
{
[Required(ErrorMessage = "File Content should be given"),Display(Name = "File Content", Prompt = "Please Give File Content")]
public IFormFile XmlFile { get; set; }
[Display(Name = "Previous Signed/Unsigned File", Prompt = "Please select Previous File")]
public long? PreviousFileId { get; set; }
}
globals.gs: 我创建了一个名为Globals的工作表,在其中存储了一些工作表名称和电子表格的ID,然后在清除内容之前将主表复制到该工作表中。
type = "module"
Codes.gs: 我在这里有一个菜单设置。
function archiveDaily() {
const mshsr=4;
const ss=SpreadsheetApp.getActive();
const msh=ss.getSheetByName('Master');
const dss=SpreadsheetApp.openById(getGlobal('MasterSheetsLogId'));//open master archive
const ts=Utilities.formatDate(new Date(), Session.getScriptTimeZone(), "MM/dd/yy HH:mm:ss")
msh.copyTo(dss).setName(ts);//copies current master sheet to master archive not sure if you would want this but I would
if(msh.getLastRow()-mshsr+1>0) {
msh.getRange(mshsr,1,msh.getLastRow()-mshsr+1,msh.getLastColumn()).clearContent();
}
const nA=getGlobal('DailySheetNames').split(',');//sheet name store in Globals sheet as a hash table
const dt=new Date();
const td=new Date(dt.getFullYear(),dt.getMonth(),dt.getDate()).valueOf();//start of day
const to=new Date(dt.getFullYear(),dt.getMonth(),dt.getDate()+1).valueOf();//end of day
const dshsr=4;
nA.forEach(function(name,i){
let dsh=ss.getSheetByName(name);
let drg=dsh.getRange(dshsr,1,dsh.getLastRow()-dshsr+1,dsh.getLastColumn());
let v=drg.getDisplayValues();
let mv=[[dsh.getName(),'','','','','','','','','','','','','','','','']];//Display Sheetname on top of every group
v.forEach(function(r,i){
let idt=new Date(r[0]).valueOf();
//Select rows that fall between midnights
if(idt>td && idt<to) {
mv.push(r);
}
});
msh.getRange(msh.getLastRow()+1,1,mv.length,mv[0].length).setValues(mv);//Put each sheets data into master sheet
});
}
function createDailyTrigger() {
var ss=SpreadsheetApp.getActive();
//This line keeps you from creating more than one trigger
if(!isTrigger('archiveDaily')) {
ScriptApp.newTrigger('archiveDaily').timeBased().everyDays(1).atHour(23).create();
}
}
其中一张纸的图像:
数据表之一的csv:
//Filename: triggers.gs
function deleteTrigger(triggerName){
var triggers=ScriptApp.getProjectTriggers();
for (var i=0;i<triggers.length;i++){
if (triggerName==triggers[i].getHandlerFunction()){
ScriptApp.deleteTrigger(triggers[i]);
}
}
}
function isTrigger(funcName){
var r=false;
if(funcName){
var allTriggers=ScriptApp.getProjectTriggers();
for(var i=0;i<allTriggers.length;i++){
if(funcName==allTriggers[i].getHandlerFunction()){
r=true;
break;
}
}
}
return r;
}
function deleteAllTriggers(){
var triggers=ScriptApp.getProjectTriggers();
for (var i=0;i<triggers.length; i++){
ScriptApp.deleteTrigger(triggers[i]);
}
}
function displayProjectTriggers() {
var tA=ScriptApp.getProjectTriggers();
var html="<style>th,td{border:1px solid black;padding:2px;margin:2px;}</style><table><tr><th>Handler Function</th><th>Trigger Type</th><th>Unique ID</th><td> </td></tr>";
for(var i=0;i<tA.length;i++) {
html+=Utilities.formatString('<tr><td>%s</td><td>%s</td><td>%s</td><td><input type="button" value="Delete" onClick="google.script.run.withSuccessHandler(function(){google.script.run.displayProjectTriggers();}).deleteTrigger(\'%s\');" /></td></tr>',tA[i].getHandlerFunction(),tA[i].getEventType(),tA[i].getUniqueId(),tA[i].getHandlerFunction());
}
html+='</table><br /><input type="button" value="Close" onClick="google.script.host.close();" />';
var userInterface=HtmlService.createHtmlOutput(html).setWidth(800);
SpreadsheetApp.getUi().showModelessDialog(userInterface, 'Project Triggers');
}
母版纸的图片
用于主表的csv:
function getGlobals(){
var ss=SpreadsheetApp.getActive();
var sh=ss.getSheetByName('Globals');
var rg=sh.getRange(1,1,sh.getLastRow(),2);
var vA=rg.getValues();
var g={};
for(var i=0;i<vA.length;i++){
g[vA[i][0]]=vA[i][1];
}
return g;
}
function setGlobals(dfltObj){
var dfltH=Object.keys(dfltObj).length;
if(dfltObj){
var ss=SpreadsheetApp.getActive();
var sh=ss.getSheetByName('Globals');
var rg=sh.getRange(1,1,dfltH,2);
var vA=rg.getValues();
for(var i=0;i<dfltH;i++){
vA[i][1]=dfltObj[vA[i][0]];
}
rg.setValues(vA);
}
}
function getGlobal(name){
return getGlobals()[name];
}
function setGlobal(name,value){
var curObj=getGlobals();
if(!curObj.hasOwnProperty(name)) {
var ss=SpreadsheetApp.getActive();
var sh=ss.getSheetByName('Globals');
sh.appendRow([name,value])
}else{
curObj[name]=value;
setGlobals(curObj);
}
}
function cleanGlobals() {
var ss=SpreadsheetApp.getActive();
var sh=ss.getSheetByName('Globals');
if(sh.getLastColumn()>2) {
sh.getRange(1,3,sh.getLastRow(),sh.getLastColumn()-2).clearContent();
}
var rg=sh.getRange(1,1,sh.getLastRow(),2);
var vA=rg.getValues();
for(var i=0;i<vA.length;i++) {
if(!vA[i][0] || !vA[i][1]) {
var userInterface=HtmlService.createHtmlOutput('Globals Sheet Requires Maintenance...Do it know.' + ' Check Row ' + Number(i + 1));
SpreadsheetApp.getUi().showModelessDialog(userInterface, 'Global Maintenance Required');
break;
}
}
}
答案 2 :(得分:1)
脚本的简化版本:
//@OnlyCurrentDoc
function merge() {
const ss = SpreadsheetApp.getActive();
const arr = ss
.getSheets()
.filter(s => !s.getName().includes('Master'))//exclude Master sheet
.flatMap(s => s.getDataRange().getValues());//map sheet to values and flatten it
ss.getSheetByName('Master')
.getRange(1, 1, arr.length, arr[0].length)
.setValues(arr);
}
已修改
答案 3 :(得分:1)
以下脚本执行以下操作:
1)不论其他标签的命名约定如何,都必须每日存档(仅主标签需要正确命名)
2)忽略其他选项卡中的标题行(假定主菜单具有标题行)
3)每天触发
4)新增了归档以前的母版的功能,以防脚本在访问数据之前运行-仅1天归档
EverydayTrigger函数创建每日循环,而MergeSheet函数是合并工作表的主要脚本。每一行脚本的解释都在脚本本身中。
function EverydayTrigger() {
ScriptApp.newTrigger("MergeSheets")
.timeBased()
.everyDays(1)
.create();
}
function MergeSheets() {
var app = SpreadsheetApp;
var ss = app.getActiveSpreadsheet();
var data = null;
var RetrieveSheet = null;
var PasteSheet = ss.getSheetByName("Master");
/*
// Use this if you are using the archiving option
var PrevArchSheetName = PasteSheet.getRange(1,1000).getValue();
if(PrevArchSheetName.length > 1){
var PrevArchSheet = ss.getSheetByName(PrevArchSheetName); //Retrieve the stored Archive Sheet's Name
ss.deleteSheet(PrevArchSheet);
}
*/
var sheets = ss.getSheets();//get all sheets regardless of naming conventions (allow you to expand your data source)
/*
//This portion can be used to allow for archiving of the previous day data in case you still need it.
var ArchiveSheet = ss.insertSheet(new Date() + "Master");
PasteSheet.getDataRange().copyTo(ArchiveSheet.getRange(1,1));
PasteSheet.getRange(1,1000).setValue(ArchiveSheet.getName()); // stores the name of the sheet so as to delete it when the script run again
*/
PasteSheet.getRange(2,1,PasteSheet.getLastRow(),PasteSheet.getLastColumn()).clear();//removes all old information
for (var i =0; i<sheets.length; i++){
RetrieveSheet = ss.getSheetByName(sheets[i].getName());
if (RetrieveSheet.getName() != 'Master'){
//data = RetrieveSheet.getDataRange(); //use this if you want the header row for each salesperson
data = RetrieveSheet.getRange(2,1,RetrieveSheet.getLastRow(),RetrieveSheet.getLastColumn()); //presuming you dont want the header rows
data.copyTo(PasteSheet.getRange(parseInt(PasteSheet.getLastRow())+1,1));
}
}
}
答案 4 :(得分:0)
正如其他人所说,= query({},“ select * where col1!=”“)是对此的最佳解决方案。
此外,它通过API调用链接到我们的数据库。
感谢卡斯珀你的传奇!
自动化ftw!