【问题标题】:Macro: Copying values from one sheet to another, depending on sheet name, and specific columns宏:将值从一个工作表复制到另一个工作表,具体取决于工作表名称和特定列
【发布时间】:2020-02-25 23:22:20
【问题描述】:

第一次在这里发帖,对谷歌脚本编码很陌生,所以我很感激能得到任何帮助。

我正在尝试设计一个宏,并且已经经历了一些线程,但还没有找到合适的东西。我试图将这个过程设计为我可以想象的对程序友好,希望它会有所帮助。设置如下:

该宏用于从 MainSheet 上的 Column1 和 Column2 复制数据,并根据 SheetName 和 Date 列上提供的信息,将其粘贴到辅助工作表上的相应单元格上。对 MainSheet 上的每个条目重复此过程。

我这里是过程的图片示例:Example MainSheetExample SheetAExample SheetB

再次,如果我能得到任何帮助,我将不胜感激。非常感谢!

编辑:这是示例 Google 表格电子表格的 Link

--- 瓦拉兹

【问题讨论】:

  • 嗨 Valraz,欢迎来到 Stackoverflow!我想知道日期列的一些事情:它的行为如何?同一张工作表可以有多行具有相同的日期吗?另外,我想 SheetA, SheetB... 的记录也应该按此字段排序?最后,为了记录,请记住下次附上示例表格文档而不是图像。 ;)
  • 嗨,卡尔,感谢您与我们联系!回答您的问题: 1) 辅助表中的日期列是一个时间线,其中随着一年中每个月的过去,每个月都会添加一个新条目。每个月只有一个记录。 2) 是的,次要工作表记录将随着时间的推移按日期排序。 3) 当然,我会马上看到如何附加示例文档:D
  • 为什么不用查询,我觉得比较简单

标签: google-apps-script google-sheets


【解决方案1】:

此函数将在表格 A、B... 中查找与主表格中的列匹配的列,并将该数据附加到 ColumnA 中的表格名称中。它不关心工作表中的列是如何布置的。所以它的运行速度比假设修复布局要慢一些。但是我一直在用同样的方式做这件事感到无聊。

function copyData() {
  var ss=SpreadsheetApp.getActive();
  var msh=ss.getSheetByName('MainSheet');
  var mrg=msh.getRange(1,1,msh.getLastRow(),msh.getLastColumn());
  var vA=mrg.getValues();
  var hA=vA[0];
  var hObj={};
  hA.forEach(function(e,i){if(e){hObj[e]=i;}});
  vA.forEach(function(row,i){
    if(i>0) {
      var pA=[];
      var sh=ss.getSheetByName(row[hObj['SheetName']]);
      var shA=sh.getRange(1,1,1,sh.getLastColumn()).getValues()[0];
      var shObj={};
      shA.forEach(function(e,i){if(e){shObj[e]=i;}});
      row.forEach(function(c,j){
        if(shObj.hasOwnProperty(hA[j])) {
          pA.push(c);
        }
      });
      sh.appendRow(pA);
    }
  });
}

这是直接的方法。

function copyData1() {
  var ss=SpreadsheetApp.getActive();
  var msh=ss.getSheetByName('MainSheet');
  var mrg=msh.getDataRange();
  var vA=mrg.getValues();
  vA.forEach(function(r,i){
    if(i>0) {
      var sh=ss.getSheetByName(r[0]);
      sh.appendRow([r[1],r[2],r[3]],r[4]);//Modified for more columns
    }
  });
}

【讨论】:

  • 嘿库珀,非常感谢您的时间和帮助!我马上试试。
  • 请注意,我附加了直接的方法来做这件事,这更容易和更快。
  • 您可以通过在工作表名称上使用 switch 语句来针对不同工作表布局进行简单的操作。
  • 这些是我在尝试了这两个脚本后的发现: 1) 两者都将新行复制到辅助工作表中,而不是使用其中已经存在的日期。这没问题,我可以完美地处理它(谢谢!)。 2)我尝试在 MainSheet 和辅助工作表(Column3)中添加第三列,并且只有 copyData() 将其集成到流程中。由于某种原因 copyData1() 忽略了新列的存在。 3)我还尝试在混合物中添加第三张辅助纸(SheetC),效果很好。非常感谢您的帮助!
  • 第二个版本是硬连线的。如果您更改结构,您已经更改了代码。至于日期问题,第一个版本只是复制,也许公式有问题。如果您可以分享您的工作表,我会修复它
【解决方案2】:

我猜这是一个重要问题,您的工作表 A 和工作表 B 是如何接收数据的?是插入数据的人还是在做的脚本?

【讨论】:

  • 嗨,Kev,感谢您与我们联系。我一定是解释自己失败了,我会再试一次。这个想法是让宏将数据从 MainSheet 复制到辅助工作表中的适当单元格(在本例中为 SheetA 和 SheetB)。将输入 MainSheet 上的数据。
  • 当时我得到了不同的解决方案。您想在您输入的每一行之后运行该函数,还是例如每天...?
  • 我每天运行脚本都没有问题,一旦在 MainSheet 中收集了大量条目
【解决方案3】:

在工作表 A 中输入以下公式:

=QUERY(MainSheet!A:D,"select * where A='Sheet A'",-1)

在表 B 中输入以下公式:

=QUERY(MainSheet!A:D,"select * where A='Sheet B'",-1)

您也可以在宏或 Google 应用脚本中执行此操作

【讨论】:

  • 遗憾的是,不能使用 MainSheet 中的查询,因为我们将每月对其进行擦除。
  • 好的,我明白了,但可能会作为替代方案,您可以从查询中将结果复制到该位置,因此查询只是作为一个界面。
  • 我为此创建了
【解决方案4】:

这里正如我之前所说的使用查询,这会自动创建您的工作表并获取下一个日期:

function CopyDataFromMainSheet() {
  var spreadsheet = SpreadsheetApp.getActive();
  var mysheet;
  mysheet=spreadsheet.getSheetByName('MainSheet');
  //8 is spare columns that may be can used
  var myrange=mysheet.getRange('A1').offset(0, mysheet.getLastColumn()+8);
  myrange.setFormula('=Query(MainSheet!A2:A' + mysheet.getLastRow() + ',"Select A ,count(A) Group By A",0)'); 
  var jojo=mysheet.getRange(1,myrange.getColumn(),mysheet.getLastRow(),1).getValues();
  //Clear Query
  myrange.clear();
  for  (a=1 ;a<jojo.length;a++){
    //Create New Sheet That Not found included with header
    if(spreadsheet.getSheetByName(jojo[a][0])==null) if (jojo[a][0]!='') {
      spreadsheet.insertSheet(jojo[a][0]);
      spreadsheet.getRange('MainSheet!1:1').copyTo(spreadsheet.getSheetByName(jojo[a][0]).getRange("A1"), SpreadsheetApp.CopyPasteType.PASTE_NORMAL, false);
    }

    if(spreadsheet.getSheetByName(jojo[a][0])!=null) if (jojo[a][0]!='') {
      var myDate=new Date('1 jan 1900');

      var DestLastRow = spreadsheet.getSheetByName(jojo[a][0]).getLastRow();
      if (DestLastRow>1) myDate=new Date(spreadsheet.getSheetByName(jojo[a][0]).getRange('B' + DestLastRow).getValue());
      var dateStr = [
                  myDate.getFullYear(),
                  ('0' + (myDate.getMonth() + 1)).slice(-2),
                  ('0' + myDate.getDate()).slice(-2)
               ].join('-');
      myrange.setFormula('=Query(MainSheet!A:E,"Select * where A=\'' + jojo[a][0] + '\' and B>date \'' + dateStr + '\'",0)'); 

      var RsltRange=myrange.getA1Notation() + ":" + 
          mysheet.getRange("A1").offset(mysheet.getLastRow()-1,
          mysheet.getLastColumn()-1).getA1Notation();
      //Copy Value
      spreadsheet.getRange('MainSheet!' + RsltRange).copyTo(spreadsheet.getSheetByName(jojo[a][0]).getRange("A"+DestLastRow), SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
      //copy format
      spreadsheet.getRange('MainSheet!' + RsltRange).copyTo(spreadsheet.getSheetByName(jojo[a][0]).getRange("A"+DestLastRow), SpreadsheetApp.CopyPasteType.PASTE_FORMAT, false);

      myrange.clear();
    }
  }
};

【讨论】:

  • 我会通过这个看看是否有帮助,非常感谢! :)
  • 对不起,myrange.clear() 必须取消注释,我已经编辑过了
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-01-03
相关资源
最近更新 更多