如何在Google表格中从选定范围创建CSV文件?

时间:2019-05-14 20:02:40

标签: csv google-apps-script google-sheets export-to-csv

我们正在将信息系统从Excel迁移到Google表格,该过程的重要组成部分是可以基于多个不同范围创建多个CSV文件的功能(目前只能作为静态范围,例如“ B8:K500 “),每个CSV文件都以各自的货币为标题。我们用它发送工资单,然后将其上传到PayPal,然后用所需的信息付款([电子邮件],[货币],[美元金额] {下一位雇员的回车}

我们已经在VBA中设置了此功能,如底部所示,但是我不精通Javascript,更不用说Google Apps Script了,我不确定从哪里开始。

我发现了一些几乎在其中的示例代码,但是当我运行它时,它显示错误“指定的范围必须是工作表的一部分。(第5行,文件“ Csv New”)” 并在调试后,将(文件夹,i,工作表和csvFile)变量显示为未定义,而(range)列为(Object(1951973745))。可以在这里找到此代码:

function ExportCSV() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheets = ss.getSheets();
  var range = ss.getSheets()[0].getRange("B8:K500");
   SpreadsheetApp.setActiveRange(range);

  // create a folder from the name of the spreadsheet
  var folder = DriveApp.createFolder(ss.getName().toLowerCase().replace(/ /g,'_') + '_csv_' + new Date().getTime());
  for (var i = 0 ; i < sheets.length ; i++) {
    var sheet = sheets[i];
    // append ".csv" extension to the sheet name
    fileName = sheet.getName() + ".csv";

    // convert all available sheet data to csv format
    var csvFile = convertRangeToCsvFile_(fileName, sheet);

    // create a file in the Docs List with the given name and the csv data
    folder.createFile(fileName, csvFile);
  }
  Browser.msgBox('Files are waiting in a folder named ' + folder.getName());
}


function convertRangeToCsvFile_(csvFileName, sheet) {  
   // get available data range in the spreadsheet
  var range = sheet.getRange("B8:K500"); 
  var values = SpreadsheetApp.getActiveSheet().getRange("B8:K500").getValues();

  var csvFile = values;
  DriveApp.createFile("mycsv.csv", csvFile);

  }

这可能是与是否发布有关的权限问题吗?我在StackOverflow中发现了类似的问题,

Google Script Cannot call FormApp.getUi() from this context

How to export google sheet as CSV by selected columns

但是他们没有直接击中解决这里遇到的问题。

让我知道是否可以提供其他信息!

谢谢:)

关联的VBA代码:

Sub WritePaypal(ByVal thisRange As Range, ByVal filePath As String, Optional ByVal fileAppend As Boolean = False)
    Dim cLoop As Long, rLoop As Long
    Dim ff As Long, strRow As String

    ff = FreeFile
    If fileAppend Then
        Open filePath For Append As #ff
    Else
        Open filePath For Output As #ff
    End If

    For rLoop = 1 To thisRange.Rows.Count
        strRow = ""
        For cLoop = 1 To thisRange.Columns.Count
            If cLoop > 1 Then strRow = strRow & vbTab
            strRow = strRow & thisRange.Cells(rLoop, cLoop).Value
        Next                                     'cLoop
        Print #ff, strRow
    Next                                         'rLoop

    Close #ff

    Range("A1").Activate
    MsgBox "Done"
End Sub

Sub WriteFile(ByVal curr As String, ByVal rng As Range)
    Dim myPath As String
    Dim filePath As String
    Dim myrng As Range
    Dim Cell As Range

    'Initialize
    myPath = ""


    ' User chooses path to save .txt file to
    With Application.FileDialog(msoFileDialogFolderPicker)
        .Title = "Select Location to Save File to"
        .AllowMultiSelect = False
        If .Show <> -1 Then GoTo NextCode
        myPath = .SelectedItems(1) & Application.PathSeparator
    End With


    'In Case of Cancel
NextCode:
    If myPath = "" Then Exit Sub

    filePath = myPath & curr & ".txt"

    'To Test
    'MsgBox myPath
    'MsgBox filePath


    On Error Resume Next
    Set myrng = rng

    If myrng Is Nothing Then
        MsgBox "No cells selected"
        Exit Sub
    Else
        WritePaypal myrng, filePath, False
    End If

    ScreenUpdating = True


End Sub

Sub WriteUSD()
    Call WriteFile("USD", Range("Z5:AB26"))
End Sub

Sub WriteAUD()
    Call WriteFile("AUD", Range("Z30:AB32"))
End Sub

Sub WriteGBP()
    Call WriteFile("GBP", Range("Z35:AB35"))
End Sub

1 个答案:

答案 0 :(得分:0)

您应该使用getActiveRangeList(),这将使您获得用户做出的多个选择。从这些ranges中,您可以获得values,然后编译CSV。

我在下面附加了示例代码,以非常简单的方式向您显示了如何执行此操作。请注意,它不处理选择大小不同的情况(例如,您选择了5封电子邮件,但金额为20美元)。该示例代码还不包括用于文件夹创建/命名或消息框的现有功能。

function createCsvFromSelections() {
  var activeRanges = SpreadsheetApp.getActiveRangeList().getRanges();
  var mergedData = [];

  // Loop through the ranges, rows, and columns in that order so that the
  // values can be recorded in the correct order.
  for (var i in activeRanges) {
    var values = activeRanges[i].getValues(); // 2-d array, row[]col[]
    for (var rowIndex in values) {
      var row = values[rowIndex];
      if (!Array.isArray(mergedData[rowIndex])) // Check if a row was already created
          mergedData[rowIndex] = []; // Add a blank row to push the values into
      for (var colIndex in row) {
        mergedData[rowIndex].push(row[colIndex]);
      }
    }
  }

  // Convert mergedData array to CSV string
  var csvData = "";
  for (var rowIndex in mergedData) {
    csvData += (mergedData[rowIndex].join(",") + "\n");
  }

  // Create the file
  DriveApp.createFile("2019-05-15 Selections", csvData, MimeType.CSV);
}