OutOfBoundsException on WebListBox2017

Hi, I am new in Xojo. I´m working on a project in which I have to export the contens of a WebListBox as a .csv, I´ve tried adapting the answers on this link but i´m unable to make it work
Sincerly I don´t know why, when exporting a WebListBox as a folderitem in Xojo2017 (with MBS plugins) I get an error saying: “Attempted to access cell -1,-1 but limit is -1,8.”.
Here is the code I´m using:

Function exportCSV(extends lb As WebListbox) As folderitem

Dim excelOut As TextOutputStream

Dim f as FolderItem

f= SpecialFolder.Documents.child("test.csv")

excelOut = TextOutputStream.Create(f)

if excelOut <> nil then
  
  excelOut.Write lb.cell(-1,-1).ReplaceAll(chr(9),",")
  
  excelOut.Close
  
end if

return f

End Function

When using excelOut.Write lb.cell(1,1) i get an output of only one cell and so far is the only way it works. Any answer will be greatly appreciated.

The Cell(-1, -1) trick from Desktop doesn’t appear to be documented for Web 1.0 Listbox.

You should still be able to build your own document by iterating the rows and columns.

Thanks for replying.

  For row As integer = 0 to rowCount
    redim rowOut(-1)
    For column As Integer = 0 to columnCount
      rowOut.Append lb.Cell(row,column)
    Next
    excelOut.WriteLine chr(34) + Join(rowOut,chr(34) + "," + chr(34)) + chr(34)
  next
  excelOut.Close
end if

Would it look like something like this? (credits to @Peter_Fargo in Listbox to Excel )

That looks like it should work.

Dim ColumnCount, RowCount As Integer
Dim rowOut() as string
Dim excelOut As TextOutputStream
Dim f as FolderItem

f= SpecialFolder.Documents.child("test.csv")
excelOut = TextOutputStream.Create(f)

if excelOut <> nil then
 
  For row As integer = 0 to rowCount
    redim rowOut(-1)
    For column As Integer = 0 to columnCount
      rowOut.Append lb.Cell(row,column)
    Next
    excelOut.WriteLine chr(34) + Join(rowOut,chr(34) + "," + chr(34)) + chr(34)
  next
  excelOut.Close
  
end if

return f

I´ve tried using it like this, but still I only get a .csv file with only one cell worth of content while in the weblistbox i have 30 entries with 8columns each.

You have to set the ColumnCount and RowCount variables to the Listbox values so that the loop will perform more than one time.

may you show me how please? i don´t really get the grasp of what you are saying

Sure :slight_smile: I tend to go for the “give enough information for someone to discover the solution” approach, but am always happy to help if more is needed.

What’s happening is that you’ve defined the Dim ColumnCount, RowCount As Integer variables, but they are both 0. Since they are zero, the loops only iterate once.

Here’s how I would refactor and prettify this method:

Public Sub ExportAsCSV(extends lb as WebListbox, fTarget as FolderItem)
  // Because asking for a FolderItem is not always thread safe
  // I've designed this method to accept an already constructed FolderItem
  
  // This function also assumes you asked the user if they want to overrwite 
  // the file because it will overwrite exsiting files (generally the save dialog does this)
  
  // This is where the rows will be stored
  dim arsRows() as String
  
  dim iColMax as Integer = lb.ColumnCount - 1
  dim iRowMax as Integer = lb.RowCount - 1
  
  // Iterate the rows and columns of the listbox
  for iRow as Integer = 0 to iRowMax
    dim arsThisRow() as String
    
    for iCol as Integer = 0 to iColMax
      // Include the quotes inside the field
      arsThisRow.Append(chr(34) + lb.Cell(iRow, iCol) + chr(34))
      
    next iCol
    
    // Add this row to all our rows
    arsRows.Append(Join(arsThisRow, ","))
    
  next iRow
  
  // All rows are now ready
  dim sRowsOut as String = Join(arsRows, EndOfLine.UNIX)
  
  // Create the file (overwriting what that may exist)
  dim tos as TextOutputStream = TextOutputStream.Create(fTarget)
  
  // Write it all out
  tos.Write(sRowsOut)
  tos.Close
  
End Sub

I refactored a little as well. Acquiring a FolderItem isn’t always thread safe, so to make this function thread safe it expects you pass it a FolderItem. This makes the code a little more transportable between projects (and other forum readers!)

You would use my version like this

// Get the FolderItem
dim fDestination as FolderItem = SpecialFolder.Documents.child("test.csv")

// Write to CSV
MyWebListbox1.ExportAsCSV(fDestination)

Hopefully this helps. Let us know if you have more questions. Happy coding!

4 Likes

Your help is greatly appreciated, thanks for the effort and the convinience.