Problema "Errore di I/O" con kill()

Creare una macro - Scrivere uno script - Usare le API
Rispondi
Avatar utente
giuserpe
Messaggi: 127
Iscritto il: mercoledì 23 aprile 2014, 12:53

Problema "Errore di I/O" con kill()

Messaggio da giuserpe »

Ciao,
è da qualche giorno che sto perdendo il genio dietro ad un "Errore di I/O" con kill().
In pratica sto lavorando al travaso dei dati da un file di Calc ad un altro.
Ho il file 1113.ods da cui faccio partire la procedura che esegue questi passi:
1. copia 1113.ods in 1113-backup.ods su disco.
2. salva 1113.ods in 1113-tmp.ods
3. crea un nuovo 1113.ods in cui riversa i dati da 1113-tmp.ods
4. salva 1113.ods
5. chiude 1113-tmp.ods e lo cancella

Va tutto bene fino a quando, alla fine, il kill() manda LibreOffice in ERRORE DI I/O

Qui di seguito, per brevità, c'è la macro che sintetizza i punti 4. e 5., che così com'è funziona, ma inserita nel contesto complessivo genera l'errore.

Codice: Seleziona tutto

Sub salva_chiudi_cancella
rem ----------------------------------------------------------------------
rem 4. salva 1113.ods
' salvo il doc corrente
	oDocFrame = ThisComponent.getCurrentController().getFrame()
	oDispatchHelper = createUnoService("com.sun.star.frame.DispatchHelper")
	oDispatchHelper.executeDispatch(oDocFrame, ".uno:Save", "", 0, Array())
rem ----------------------------------------------------------------------
rem 5. chiude 1113-tmp.ods e lo cancella
' chiudo il doc -tmp
sUrl = converttourl ("W:\_tmp\1113-tmp.ods")
rem ----------------------------------------------------------------------
	Target = StarDesktop.loadComponentFromURL(sUrl, "_default",0 , Array()) 
	aFocusEvent = CreateUnoStruct("com.sun.star.awt.FocusEvent")
	Target.getCurrentController().getFrame().focusGained(aFocusEvent)
rem ----------------------------------------------------------------------
	If HasUnoInterfaces(thisComponent, "com.sun.star.util.XCloseable") Then
		thisComponent.close(true)
	Else
		thisComponent.dispose()
	End If
rem ----------------------------------------------------------------------
' cancello il doc -tmp
	Kill(sUrl)
rem ----------------------------------------------------------------------
End Sub
Qualcuno sa darmi una dritta? Esiste un'alternativa a kill()?
LibreOffice fresh su Windows e Linux
Gaetanopr
Volontario
Volontario
Messaggi: 3300
Iscritto il: mercoledì 21 novembre 2012, 20:07

Re: Problema "Errore di I/O" con kill()

Messaggio da Gaetanopr »

Secondo me fai troppi passaggi, dovresti allegare tutte le macro e spiegare cosa vuoi ottenere come risultato finale.
L'errore che esce fuori dovrebbe nascere dal fatto che vuoi eliminare un file aperto che è quello da dove lanci la macro.
Analizzando il punto 2 "salva 1113.ods in 1113-tmp.ods "
una volta salvato il file corrente in 1113-tmp.ods, il file corrente diventa questo(1113-tmp.ods), in seguito al punto 5 vuoi chiuderlo ed eliminarlo con la conseguenza che se lo chiudi questo non viene eliminato in quanto l'istruzione non viene più letta se non viene chiuso và in errore in quanto vuoi eliminare un file in uso.
Non so se sono stato chiaro

PS: Secondo me la soluzione sarebbe quella di modificare il punto 3
Attualmente tu fai questo "3. crea un nuovo 1113.ods in cui riversa i dati da 1113-tmp.ods "
Invece di creare un nuovo file dovresti salvare il file corrente(1113-tmp.ods) su 1113.ods, in questo modo non ti trovi più sul file temporaneo, quindi chiudi e cancelli quest ultimo.
LibreOffice 7.2.2.2 windows 10
Openoffice 4.1.13 su windows 10
Avatar utente
giuserpe
Messaggi: 127
Iscritto il: mercoledì 23 aprile 2014, 12:53

Re: Problema "Errore di I/O" con kill()

Messaggio da giuserpe »

Ciao,
prima di chiudere il file così:

Codice: Seleziona tutto

rem ----------------------------------------------------------------------
   If HasUnoInterfaces(thisComponent, "com.sun.star.util.XCloseable") Then
      thisComponent.close(true)
   Else
      thisComponent.dispose()
   End If
rem ----------------------------------------------------------------------
passo il focus sull'altro così:

Codice: Seleziona tutto

rem ----------------------------------------------------------------------
   Target = StarDesktop.loadComponentFromURL(sUrl, "_default",0 , Array()) 
   aFocusEvent = CreateUnoStruct("com.sun.star.awt.FocusEvent")
   Target.getCurrentController().getFrame().focusGained(aFocusEvent)
rem ----------------------------------------------------------------------
Quindi ritengo sia giusto.
In quanto a mettere qui tutto il codice mi diventa difficile, ma lo si può prendere da leeno.org scaricando una delle nigthly builds. Altrettanto, per provare la macro che si chiama da_vecchi_template_a_192, tocca avere a disposizione un vecchio file... magari questo: http://goo.gl/94XLvH
Mi rendo conto che diventa un vero e proprio lavoro... Intanto proverò a ristudiare il tutto.
LibreOffice fresh su Windows e Linux
patel
Volontario attivo
Volontario attivo
Messaggi: 4020
Iscritto il: venerdì 30 aprile 2010, 8:04
Località: Livorno

Re: Problema "Errore di I/O" con kill()

Messaggio da patel »

Quoto Gaetano, mi ha preceduto di poco, il tuo procedimento è troppo contorto.
-------------------
Libre Office 7.5.3.2 su Windows 11
allega un file di esempio, guadagnerai tempo tu e lo farai risparmiare a chi ti aiuta
Avatar utente
giuserpe
Messaggi: 127
Iscritto il: mercoledì 23 aprile 2014, 12:53

Re: Problema "Errore di I/O" con kill()

Messaggio da giuserpe »

Mi sembra l'unico modo per riversare dei dati (adattandoli) da un file ad un nuovo file senza disorientare l'utente che alla fine si ritroverebbe un file.ods ed un file-backup.ods.
Al momento, invece, si ritrova anche un file-tmp.ods che deve cancellare per conto suo, se kill() non va.
Va bene, è contorno anche troppo. Ma mi sto muovendo in modo che per l'utente sia lineare.
Non avete suggerimenti?
LibreOffice fresh su Windows e Linux
Avatar utente
giuserpe
Messaggi: 127
Iscritto il: mercoledì 23 aprile 2014, 12:53

Re: Problema "Errore di I/O" con kill()

Messaggio da giuserpe »

Gaetanopr ha scritto:PS: Secondo me la soluzione sarebbe quella di modificare il punto 3
Attualmente tu fai questo "3. crea un nuovo 1113.ods in cui riversa i dati da 1113-tmp.ods "
Invece di creare un nuovo file dovresti salvare il file corrente(1113-tmp.ods) su 1113.ods, in questo modo non ti trovi più sul file temporaneo, quindi chiudi e cancelli quest ultimo.
Purtroppo il nuovo file non è creato da zero, ma fa riferimento ad un template, anche abbastanza complesso, compreso nel pacchetto OXT e già pronto per fare determinate operazioni. Ricreare da zero quel template via Basic per me sarebbe il massimo, ma è troppo: contiene diversi fogli già preimpostati ed anche del codice Basic.
Mi sarei risparmiato ben volentieri il punto 3. ma è indispensabile.
LibreOffice fresh su Windows e Linux
Avatar utente
giuserpe
Messaggi: 127
Iscritto il: mercoledì 23 aprile 2014, 12:53

Re: Problema "Errore di I/O" con kill()

Messaggio da giuserpe »

Ribadisco però: la macro fa tutto quel che deve dal "travaso" dei dati, al salvataggio e fino alla chiusura del -tmp.
L'istruzione kill() è all'ultima riga. Tant'è che dà l'errore I/O e manda in crash LibreOffice, ma non perdo nessun dato in quanto già salvato.
LibreOffice fresh su Windows e Linux
Avatar utente
unlucky83
Volontario
Volontario
Messaggi: 2355
Iscritto il: lunedì 7 gennaio 2013, 1:23
Località: Latina

Re: Problema "Errore di I/O" con kill()

Messaggio da unlucky83 »

giuserpe ha scritto: passo il focus sull'altro così:

Codice: Seleziona tutto

rem ----------------------------------------------------------------------
   Target = StarDesktop.loadComponentFromURL(sUrl, "_default",0 , Array()) 
   aFocusEvent = CreateUnoStruct("com.sun.star.awt.FocusEvent")
   Target.getCurrentController().getFrame().focusGained(aFocusEvent)
rem ----------------------------------------------------------------------
Quindi ritengo sia giusto.
mmm...sarò banale, ma la macro è salvata sul file o nelle librerie globali?perchè puoi spostare il focus da un file ad un altro, ma non puoi cancellare la libreria delle macro in esecuzione. Quando ti da l'errore, l'ide di basic ti evidenzia il kill() di quale libreria?
LibO:Versione: 6.2.8.2
Build ID: 1:6.2.8~rc2-0ubuntu0.16.04.1- 32-bit
-
Se risolvi:
1. Condividi la soluzione qui con noi
2. Metti [Risolto] al titolo del primo messaggio come spiegato qui
Avatar utente
giuserpe
Messaggi: 127
Iscritto il: mercoledì 23 aprile 2014, 12:53

Re: Problema "Errore di I/O" con kill()

Messaggio da giuserpe »

No no... ovvio. Le macro che eseguono queste operazioni sono fuori dal file.
LibreOffice fresh su Windows e Linux
Avatar utente
unlucky83
Volontario
Volontario
Messaggi: 2355
Iscritto il: lunedì 7 gennaio 2013, 1:23
Località: Latina

Re: Problema "Errore di I/O" con kill()

Messaggio da unlucky83 »

Codice: Seleziona tutto

rem 5. chiude 1113-tmp.ods e lo cancella
' chiudo il doc -tmp
sUrl = converttourl ("W:\_tmp\1113-tmp.ods")
rem ----------------------------------------------------------------------
   Target = StarDesktop.loadComponentFromURL(sUrl, "_default",0 , Array())
Ci stavo ripensando...nel commento hai scritto "chiude 1113-tmp.ods", ma in realtà con il loadComponentFromURL lo apri. E' vero che poi lo richiudi con close(), però se era già aperto per "fare il travaso dei dati", dopo il loadComponentFromURL, ti ritrovi due file 1113-tmp.ods aperti, ma lo chiudi solo una volta.
A quel punto, il Kill va in errore, perchè il file è aperto.
LibO:Versione: 6.2.8.2
Build ID: 1:6.2.8~rc2-0ubuntu0.16.04.1- 32-bit
-
Se risolvi:
1. Condividi la soluzione qui con noi
2. Metti [Risolto] al titolo del primo messaggio come spiegato qui
Avatar utente
giuserpe
Messaggi: 127
Iscritto il: mercoledì 23 aprile 2014, 12:53

Re: Problema "Errore di I/O" con kill()

Messaggio da giuserpe »

Uso

Codice: Seleziona tutto

Target = StarDesktop.loadComponentFromURL(sUrl, "_default",0 , Array())
per prendere il focus del documento prima di poterlo chiudere con

Codice: Seleziona tutto

thisComponent.close(true)
In effetti è un problema che mi sono posto, ma non conosco altro sistema per prendere il focus di un file.
LibreOffice fresh su Windows e Linux
Avatar utente
unlucky83
Volontario
Volontario
Messaggi: 2355
Iscritto il: lunedì 7 gennaio 2013, 1:23
Località: Latina

Re: Problema "Errore di I/O" con kill()

Messaggio da unlucky83 »

Ti può essere utile qualcosa del genere per chiudere un file già aperto?

Codice: Seleziona tutto

Sub Main
oEnum=stardesktop.components.createEnumeration()
do
	if not oEnum.hasmoreElements() then exit do
	oComp=oEnum.nextelement()
	msgbox oComp.CurrentController.Title
	iF oComp.title="NomeFile.ods" then
		oComp.CurrentController.getFrame().close(true)
	end if
loop
End Sub
LibO:Versione: 6.2.8.2
Build ID: 1:6.2.8~rc2-0ubuntu0.16.04.1- 32-bit
-
Se risolvi:
1. Condividi la soluzione qui con noi
2. Metti [Risolto] al titolo del primo messaggio come spiegato qui
Avatar utente
giuserpe
Messaggi: 127
Iscritto il: mercoledì 23 aprile 2014, 12:53

Re: Problema "Errore di I/O" con kill()

Messaggio da giuserpe »

unlucky83 ha scritto:Ti può essere utile qualcosa del genere per chiudere un file già aperto?
...
Per quello che ne capisco il codice che mi proponi chiuderebbe il file anche se aperto in più sessioni.
L'ho inserito nella macro, ma il problema rimane.
Il comportamento dell'istruzione kill() sembra essere instabile: talvolta funziona bene, altre volte dà l'errore I/O ma non manda in crash LO, altre ancora lo manda in crash... mboh!
Per ora commento l'istruzione kill() e vado oltre, ma a questo punto somiglia più ad un bug visto il comportamento instabile.
Grazie
LibreOffice fresh su Windows e Linux
Avatar utente
unlucky83
Volontario
Volontario
Messaggi: 2355
Iscritto il: lunedì 7 gennaio 2013, 1:23
Località: Latina

Re: Problema "Errore di I/O" con kill()

Messaggio da unlucky83 »

Ultima prova che ti suggerisco di fare è mettere un "wait 2000" prima del kill, cosi aspetta due secondi e da il tempo di completare il close
LibO:Versione: 6.2.8.2
Build ID: 1:6.2.8~rc2-0ubuntu0.16.04.1- 32-bit
-
Se risolvi:
1. Condividi la soluzione qui con noi
2. Metti [Risolto] al titolo del primo messaggio come spiegato qui
Avatar utente
giuserpe
Messaggi: 127
Iscritto il: mercoledì 23 aprile 2014, 12:53

Re: Problema "Errore di I/O" con kill()

Messaggio da giuserpe »

sì, ci avevo già pensato ma mi ero limitato ad un wait 500 pensando che mezzo secondo fosse più che sufficiente.
Provo stanotte e ti dico.
LibreOffice fresh su Windows e Linux
Avatar utente
giuserpe
Messaggi: 127
Iscritto il: mercoledì 23 aprile 2014, 12:53

Re: Problema "Errore di I/O" con kill()

Messaggio da giuserpe »

Niente da fare.
LibreOffice fresh su Windows e Linux
Avatar utente
unlucky83
Volontario
Volontario
Messaggi: 2355
Iscritto il: lunedì 7 gennaio 2013, 1:23
Località: Latina

Re: Problema "Errore di I/O" con kill()

Messaggio da unlucky83 »

http://www.openoffice.org/api/docs/comm ... eable.html

stando a quanto dice qui, close non garantisce la cessazione del file e di sicuro non è istantaneo. Prova ad allungare il tempo di wait.

Ti allego anche un link da leggere, così fai varie prove.
https://wiki.openoffice.org/wiki/Docume ... _Documents
LibO:Versione: 6.2.8.2
Build ID: 1:6.2.8~rc2-0ubuntu0.16.04.1- 32-bit
-
Se risolvi:
1. Condividi la soluzione qui con noi
2. Metti [Risolto] al titolo del primo messaggio come spiegato qui
Rispondi