B4J Question TableView to CSV

mfstuart

Active Member
Licensed User
Longtime User
Hi all,

I'm struggling to send data from a TableView to a CSV file formatted text file.
The tableview is populated from a database.
With a button, send the TableView rows to the CSV file.

Here's the button code, which causes a crash on line: su.SaveCSV2()
B4X:
Sub btnExport_Click
    Dim Hdr As List
    Hdr.Initialize
    Hdr.Add(Array As String("ID","Title","Description","DateAdded","BaseURL","URL","Active","FileFound"))
    Dim TheItems as List = Main.tvDocs.Items
    Dim su As StringUtils
    su.SaveCSV2(File.DirApp, txtFilename.Text, ",", TheItems, Hdr)        'crashes on this line
End Sub

Here's 4 sample records from the SQL table (first line is column names):

TutorialID title description DateAdded Base_URL url Active
13 Cash Vault Deposits Cash Vault Deposits 2010-04-26 http://server:88/palace/DocumentsAn...Vault_Deposit&Change_Ordering_Instruction.pdf \\server2\DocumentsAndVideos\AccountingManual\6_Cash_Vault_Deposit%26Change_Ordering_Instruction.pdf 0
18 Cash Vault - Change Order BofA Cash Vault - Change Order BofA 2010-04-26 http://server:88/palace/DocumentsAn...ash_Vault_Deposit&Change_Ordering_Instruction BOA.pdf \\server2\DocumentsAndVideos\AccountingManual\6I_Cash_Vault_Deposit%26Change_Ordering_Instruction%20BOA.pdf 0
3 Contact Info. Accounting Contact Info 2010-04-22 http://server:88/palace/DocumentsAndVideos/AccountingManual/01_Contact_List.pdf \\server2\DocumentsAndVideos\AccountingManual\CONTACT LIST.docx 0
132 Purchasing Policies, Vendor Score Card, and Vendor Purchasing Policies, Vendor Score Card, and Vendor NULL \\server2\DocumentsAndVideos\PurchasingPolicy-PalaceJune2012.pdf 0

This is copied directly with headers from SQL Server Management Studio, so it is not formatted correctly for copying to this forum. Some columns data may contain NULL.

Here's B4J's error message:
B4X:
Error occurred on line: 45 (Export)
java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.String;
    at anywheresoftware.b4a.objects.StringUtils.SaveCSV2(StringUtils.java:74)
    at anywheresoftware.b4a.objects.StringUtils.SaveCSV(StringUtils.java:67)
    at b4j.example.export._btnexport_click(export.java:99)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:613)
    at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:228)
    at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:159)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:90)
    at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:93)
    at anywheresoftware.b4a.BA$1.run(BA.java:215)
    at com.sun.javafx.application.PlatformImpl.lambda$null$173(PlatformImpl.java:295)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.application.PlatformImpl.lambda$runLater$174(PlatformImpl.java:294)
    at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
    at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at com.sun.glass.ui.win.WinApplication.lambda$null$148(WinApplication.java:191)
    at java.lang.Thread.run(Thread.java:748)

Is it the data that's causing the crash or something else?

Thanx,
Mark Stuart
 
Last edited:

Daestrum

Expert
Licensed User
Longtime User
As an example If when you add data to the table you use
B4X:
TableView1.Items.Add(Array("aaa","bbb","ccc"))  ' these items are added as an array of Objects
and then try and use su.SaveCSV2(...) on the items you get the error

If the items were added as
B4X:
TableView1.Items.Add(Array as String("aaa","bbb","ccc")) ' these items are added as an array of Strings




Then use su.SaveCSV2(...) it will work.

java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.String;
is referring to the data in the list (from the table)


You can get round it by something like
B4X:
Dim l As List
 l.Initialize
 For Each obs() As Object In TableView1.Items
  Dim newObs() As String = obs
  l.Add(newObs)
 Next

Then use the new list 'l' in the SaveCSV2 call
 
Last edited:
Upvote 0

mfstuart

Active Member
Licensed User
Longtime User
Hi Daestrum,

B4X:
'adding data to tableview from populated variables from the SQL ResultSet
'I added "As String", as you suggested to the following line:
tvDocs.Items.Add(Array As String(ID,Title,Desc,DateAdded,BaseURL,URL,sActive,FileFound))

btnExport_Click
    Dim Hdr As List
    Hdr.Initialize
    Hdr.Add(Array As String("ID","Title","Description","DateAdded","BaseURL","URL","Active","FileFound"))
    
    Dim DocItems As List = Main.tvDocs.Items
    Dim FN As String = txtFilename.Text
    Dim su As StringUtils

    su.SaveCSV2(File.DirApp, FN, ",", DocItems, Hdr)
end Sub

Now I get this error:
java.lang.ClassCastException: [Ljava.lang.String; cannot be cast to java.lang.String

So the export is not working.
Any thoughts on that?

Thanx,
Mark Stuart
 
Upvote 0

Daestrum

Expert
Licensed User
Longtime User
Did you see the last bit I added to post #2
I would give that a try and change the table.add bit back to (array(..)) and not (Array As String(...)) in your code.
 
Upvote 0

mfstuart

Active Member
Licensed User
Longtime User
So here's what's causing the crash of this error:
java.lang.ClassCastException: [Ljava.lang.String; cannot be cast to java.lang.String

Code that exports the TableView records to CSV
B4X:
Sub btnExport_Click   
    Dim Hdr As List
    Hdr.Initialize      'if this and the next line are used to create the CSV header, the above error occurs
    Hdr.Add(Array As String("ID","Title","Description","DateAdded","BaseURL","URL","Active","FileFound"))

    ' If the above 2 lines are not used and this line is used to create the header, no error occurs
    'Hdr.Initialize2(Array As String("ID","Title","Description","DateAdded","BaseURL","URL","Active","FileFound"))
   
    Dim FN As String = txtFilename.Text
    Dim su As StringUtils
    Dim DocItems As List = Main.tvDocs.Items

    su.SaveCSV2("", FN, ",", DocItems, Hdr)
   
End Sub

So it seems like there is a B4J bug.
Erel - if you are reading this, can you please confirm?

Thanx,
Mark Stuart
 
Upvote 0

Tayfur

Well-Known Member
Licensed User
Longtime User
So here's what's causing the crash of this error:
java.lang.ClassCastException: [Ljava.lang.String; cannot be cast to java.lang.String

Code that exports the TableView records to CSV
B4X:
Sub btnExport_Click  
    Dim Hdr As List
    Hdr.Initialize      'if this and the next line are used to create the CSV header, the above error occurs
    Hdr.Add(Array As String("ID","Title","Description","DateAdded","BaseURL","URL","Active","FileFound"))

    ' If the above 2 lines are not used and this line is used to create the header, no error occurs
    'Hdr.Initialize2(Array As String("ID","Title","Description","DateAdded","BaseURL","URL","Active","FileFound"))
  
    Dim FN As String = txtFilename.Text
    Dim su As StringUtils
    Dim DocItems As List = Main.tvDocs.Items

    su.SaveCSV2("", FN, ",", DocItems, Hdr)
  
End Sub

So it seems like there is a B4J bug.
Erel - if you are reading this, can you please confirm?

Thanx,
Mark Stuart
it has not BUG
only change this line.
B4X:
Hdr.AddAll(Array As String("ID","Title","Description","DateAdded","BaseURL","URL","Active","FileFound"))
 
Upvote 0

Daestrum

Expert
Licensed User
Longtime User
Try changing
B4X:
Hdr.Add(Array As String("ID","Title","Description","DateAdded","BaseURL","URL","Active","FileFound"))

to (Uses AddAll instead of Add)
B4X:
Hdr.AddAll(Array As String("ID","Title","Description","DateAdded","BaseURL","URL","Active","FileFound"))

** beaten to it lol
 
Upvote 0

mfstuart

Active Member
Licensed User
Longtime User
That's maybe one way to work around the bug.
Have you tried the way I describe to reproduce the crash?
Open the attached B4J app and you will see how to reproduce the bug.
I've put comments in the app that shows how to make the app crash.

B4J version: 6.00

Mark
 

Attachments

  • SaveCVS2CrashDemo.zip
    28.2 KB · Views: 333
Upvote 0

DarkMann

Member
Licensed User
Longtime User
That's maybe one way to work around the bug.
Have you tried the way I describe to reproduce the crash?
Open the attached B4J app and you will see how to reproduce the bug.
I've put comments in the app that shows how to make the app crash.

B4J version: 6.00

Mark

It's very definitely not a bug in B4J. List.Add() adds a single entry to the end of the list. The error is telling you that it cannot cast a list of strings into a single string and therefore bails out. both Tayfur and Daestrum are not giving a "work around", just pointing out that List.AddAll() is the correct way to add multiple entries to a list.

I think maybe you're making an assumption that Tableview.Items.Add() and List.Add() do the same thing - or should do, but they don't.

Actually, your other way to do it (by using List.Initialize2() is probably shorter, neater and cleaner in this case as it's a local object that you need to initialize anyway and this saves a line of code.

David
 
Upvote 0
Top