首页 > 解决方案 > 从 CSV 文件中间分离数据而不使用脚本中的行号

问题描述

问题中的电子表格

我的能源供应商在一张纸上输出了一个相当混乱的 CSV 文件,其中包含多个无用标题下的数据。我只需要一种类型的数据(“E1 数据”)。

我想创建一个自动分离相关数据的脚本(在此版本中的第 244-485 行之间)。但是,随着向每个部分添加更多数据,这些行号每天都会发生变化。

每次更新 CSV 时,每个部分的标题都是一致的,我可以创建一个脚本来根据此标题中的文本(当前位于第 244 行)对数据进行排序吗?

200 6102111110 B1E1K1Q1 E1 E1 DZ152889 千瓦时 30

它必须是某种脚本,指定 上述标题(“E1 数据”)和“K1”标题(第 486 行)之间的值。

不确定这是否可能,但我对创建脚本是全新的。试着先做我的尽职调查研究!

否则我可以创建一个脚本来计算 E1 数据的起始位置并使用该值吗?我在电子表格上提出了一个公式,显示了如何找到这些行号,但不确定如何基于此制作脚本!

这是一个适用于当前电子表格的脚本,但在其他任何日子都不会,因为行会改变:

function CopyE1Data() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var source = ss.getSheets()[0];
  var destination = ss.getSheets()[1];

  var range = source.getRange("A245:AX485")
  range.copyValuesToRange(destination, 1, 2, 2, 2);
  
    }       
                                                                                                                                    

标签: google-apps-scriptgoogle-sheets

解决方案


该列A似乎指定了行的类型。使用它我们可以检测到标题(值 200),并在E1第四行中搜索我们可以检测到该标题。这是我想出的脚本(最后的纲要)

function CopyE1Data() {
 const ss = SpreadsheetApp.getActiveSpreadsheet()
 const source = ss.getSheets()[0]
 const dest = ss.getSheets()[1]
 const rows = source.getRange(1, 1, source.getLastRow()-1, 4).getValues()
 
 // Find the rows
 let i = 0
 let start
 let end
 while (i < rows.length) {
   if (rows[i][3] === 'E1') {
     start = i + 2 // +1 to skip the current row (only copy data) and +1 to convert from index to row number
     break
   } else {
     i++
   }
 }
 // The current row is the E1 header. Skip it.
 i++
 while (i < rows.length) {
   // Stop at next header or at the end of the sheet
   if (rows[i][0] === 200) {
     end = i + 1 // +1 to convert from index to row number
     break
   } else {
     i++
   }
 }
 
 // Copy values
 source.getRange(start, 1, end-start, 50).copyTo(dest.getRange(1, 1))
}

撞倒

  1. 我们得到表格和必要的数据(4 列;所有行)
  2. 我们搜索第E14 列中的行。保存下一行(我们不复制标题)。
  3. 我们跳过这一行并继续迭代,直到找到另一个标题或到达末尾。
  4. 将值复制到另一张纸。

您可能希望按名称而不是使用索引来获取工作表,因为它允许您更改顺序并在它们之前添加其他工作表。

参考


推荐阅读