Italian esportare dati

Xfood

Expert
Licensed User
Longtime User
ciao a tutti
ho un problema, non riesco ad esportare i dati da un db


allego il codice

'esporta i dati in formato csv
Sub lblExp_Click
lblExp.Enabled = False 'evita click multipli
lblImp.Visible = False
lblExp.Visible= False
'APB1.Visible = True
lblRiepilogo.Text = lblRiepilogo.Text & CRLF & "*** Export: inizio procedura ***"

Dim mlist As List
mlist.Initialize
mlist=DBUtils.ExecuteMemoryTable(DBData.SQL1,"SELECT * FROM anagrafica",Null,0)
Dim su As StringUtils
Log("=========================================")
Log("Export Inizio")

' questa la riga che mi da errore
su.SaveCSV(Starter.rp.GetSafeDirDefaultExternal(""),"archivio.csv","|",mlist)



Log("Export finito")
lblRiepilogo.Text = lblRiepilogo.Text & CRLF & "*** Export: procedura terminata ***"

lblExp.Enabled = True
lblImp.Visible = True
lblExp.Visible= True
End Sub



quando tento di salvarli mi da questo errore


vorrei se possibile salvare questo file nella cartella di default download
Grazie a chi mi dara' una mano
upload_2019-12-22_0-23-40.png
 
Sicuro che il quarto paramentro di SaveCSV rispetti la definizione?
Table - A List with arrays of strings as items. Each array represents a row. All arrays should be of the same length.

mlist.Initialize - andrebbe eliminato
 
Sicuro che il quarto paramentro di SaveCSV rispetti la definizione?
Table - A List with arrays of strings as items. Each array represents a row. All arrays should be of the same length.

mlist.Initialize - andrebbe eliminato

Grazie per la risposta, oggi appena rientro dopo pranzo provo. (SaveCSV (Dir As String, FileName As String, SeparatorChar As Char, Table As List)
non e' corretto cosi su.SaveCSV(Starter.rp.GetSafeDirDefaultExternal(""),"archivio.csv","|",mlist)
se volessi salvare il dato nella cartella di default DOWNLOAD come faccia ad intercettarla?
ho prese l'esempio di codice da qui:
https://www.b4x.com/android/forum/threads/sqllite-to-csv-and-dbutils.55487/#content

p.s. vorrei finalmente completare il mio primo progetto, sembra un parto, lo lasciato e ripreso mille volte permancanza di tempo.
Grazie mille per il tempo che mi dedicate
 
Last edited:
Prova il suggerimento di Erel:
Log(File.ReadString(File.DirInternal,"marker_data.csv")) ma riferito a mlist. Un possibile problema potrebbe derivare da dati Null.
Potresti adattare una sintassi tipo:
Code:
SELECT  ID, NAME, AGE, ADDRESS, SALARY
       FROM COMPANY
       WHERE SALARY IS NOT NULL;
per evitare righe che contengano campi a valore Null oppure definire tutti i campi come NOT NULL e quindi avere una tabella di partenza necessariamente "pulita".

ps: ho controllato e ExecuteMemoryTable ritorna il tipo corretto di dati (list of strings' arrays) per SaveCSV.

pps: https://www.b4x.com/android/forum/t...getsafedirdefaultexternal.110020/#post-686956
 
Last edited:
purtroppo non riesco ad estrarre i dati con SaveCsv()
ho riprovato cosi:
Dim List1 As List
Dim su As StringUtils
List1=DBUtils.ExecuteMemoryTable(DBData.SQL1,"SELECT * FROM anagrafica",Null,0)
su.SaveCSV(File.DirRootExternal, "Download/archivio.csv", ",",List1)
dove sbaglio..????
actsync_lblexp_click (java line: 461)
java.lang.NullPointerException: Attempt to invoke interface method 'int java.lang.CharSequence.length()' on a null object reference
ecc...


per quando riguarda l'accesso alla cartella di default DOWNLOAD ho risolto cosi:
File.DirRootExternal, "Download/archivio.csv"
Sub Activity_Resume
For Each permission As String In Array(rp.PERMISSION_READ_EXTERNAL_STORAGE,rp.PERMISSION_CAMERA,rp.PERMISSION_WRITE_EXTERNAL_STORAGE)
rp.CheckAndRequest(permission)
Wait For Activity_PermissionResult (permission As String, Result As Boolean)
If Result = False Then
ToastMessageShow("No permission!", True)
Activity.Finish
Return
End If
Next
End Sub
il manifest e questo:
AddPermission("android.permission.WRITE_EXTERNAL_STORAGE")
 
Sono stato poco chiaro. Intendevo dire di provare un log sulle righe ritornate da ExecuteMemoryMap, quindi PRIMA di passare a SaveCSV.
Il mio sospetto è che ci siano valori posti a Null e questi causino problemi con il parser che poi realizza il CSV da salvare.
Se questo fosse il caso, ti basterebbe sostituire i Null con stringa vuota
 
Sono stato poco chiaro. Intendevo dire di provare un log sulle righe ritornate da ExecuteMemoryMap, quindi PRIMA di passare a SaveCSV.
Il mio sospetto è che ci siano valori posti a Null e questi causino problemi con il parser che poi realizza il CSV da salvare.
Se questo fosse il caso, ti basterebbe sostituire i Null con stringa vuota
Grazie, hai un esempio per scorrere la mia list1 e sostituire eventuali risultati null in "" per tutti i campi e tutte le righe?
 
ho provato questo codice:
Dim su As StringUtils
Dim Data As List
Data.Initialize
Dim rs As ResultSet = DBData.SQL1.ExecQuery("SELECT * FROM anagrafica")
Do While rs.NextRow
Dim row(9) As Object
row(0) = rs.GetDouble("id")
row(1) = rs.GetString("codice")
row(2) = rs.GetString("descrizione")
row(3) = rs.GetString("prezzo")
row(4) = rs.GetString("costo")
row(5) = rs.GetString("reparto")
row(6) = rs.GetString("esistenza")
row(7) = rs.GetString("iva")
row(8) = rs.GetString("PzxC")
For i = 0 To 8
If row(i) = Null Then row(i) = ""
Next
Data.Add(row)
Loop
rs.Close
Log("lista processata")
su.SaveCSV(File.DirRootExternal, "Download/archivio.csv", ",",Data)

ma ho sempre questo errore:

lista processata
actsync_lblexp_click (java line: 489)
java.lang.ClassCastException: java.lang.Object[] cannot be cast to java.lang.String[]
at anywheresoftware.b4a.objects.StringUtils.SaveCSV2(StringUtils.java:107)
at anywheresoftware.b4a.objects.StringUtils.SaveCSV(StringUtils.java:100)
at FqGr.EasyScan.actsync._lblexp_click(actsync.java:489)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:196)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:180)
at anywheresoftware.b4a.BA.raiseEvent(BA.java:176)
at anywheresoftware.b4a.objects.ViewWrapper$1.onClick(ViewWrapper.java:80)
at android.view.View.performClick(View.java:6256)
at android.view.View$PerformClick.run(View.java:24701)
at android.os.Handler.handleCallback(Handler.java:789)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6541)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
 
Potresti modificare (quindi avere una tua versione) ExecuteMemoryTable. Non ho controllato cosa ritorna GetString2 in caso di valore Null, magari non serve nemmeno
Code:
Public Sub MyEMT(SQL As SQL, Query As String, StringArgs() As String, Limit As Int) As List
   Dim cur As ResultSet
   If StringArgs = Null Then
       Dim StringArgs(0) As String
   End If
   cur = SQL.ExecQuery2(Query, StringArgs)
   Dim table As List
   table.Initialize
   Do While cur.NextRow
       Dim values(cur.ColumnCount) As String
       For col = 0 To cur.ColumnCount - 1
           values(col) = cur.GetString2(col)
           if ((values(col) = null) or (values(col) ="null")) then values(col) = ""   '<-- unica modifica al codice originale
       Next
       table.Add(values)
       If Limit > 0 And table.Size >= Limit Then Exit
   Loop
   cur.Close
   Return table
End Sub

In alternativa, agendo sul risultato della query e conoscendo il numero di campi attesi, potresti avere qualcosa del genere:
Code:
Dim List1 As List=DBUtils.ExecuteMemoryTable(DBData.SQL1,"SELECT * FROM anagrafica",Null,0)
for i = 0 to list.size-1
  Dim values(numero di campi ritornati dalla query) As String = list1.get(i)
  For col = 0 To numero di campi ritornati dalla query - 1
       if ((values(col) = null) or (values(col) ="null")) then values(col) = ""  
  Next
Next
 
Potresti modificare (quindi avere una tua versione) ExecuteMemoryTable. Non ho controllato cosa ritorna GetString2 in caso di valore Null, magari non serve nemmeno
Code:
Public Sub MyEMT(SQL As SQL, Query As String, StringArgs() As String, Limit As Int) As List
   Dim cur As ResultSet
   If StringArgs = Null Then
       Dim StringArgs(0) As String
   End If
   cur = SQL.ExecQuery2(Query, StringArgs)
   Dim table As List
   table.Initialize
   Do While cur.NextRow
       Dim values(cur.ColumnCount) As String
       For col = 0 To cur.ColumnCount - 1
           values(col) = cur.GetString2(col)
           if ((values(col) = null) or (values(col) ="null")) then values(col) = ""   '<-- unica modifica al codice originale
       Next
       table.Add(values)
       If Limit > 0 And table.Size >= Limit Then Exit
   Loop
   cur.Close
   Return table
End Sub

In alternativa, agendo sul risultato della query e conoscendo il numero di campi attesi, potresti avere qualcosa del genere:
Code:
Dim List1 As List=DBUtils.ExecuteMemoryTable(DBData.SQL1,"SELECT * FROM anagrafica",Null,0)
for i = 0 to list.size-1
  Dim values(numero di campi ritornati dalla query) As String = list1.get(i)
  For col = 0 To numero di campi ritornati dalla query - 1
       if ((values(col) = null) or (values(col) ="null")) then values(col) = "" 
  Next
Next


ottimo funzionaaaaaaa ho utilizzato la prima tua funzione Public Sub MyEMT
grazie sei un Genio
 
sei un Genio
Per aver aggiunto una riga? pensa a chi ha scritto tutto il resto! :D
 
Back
Top