PDA

Visualizza versione completa : [VB6]- Istanza di word


gkcuvb
21-06-2004, 17.07.13
Ho sviluppato un'applicazione che crea un file di word con dei dati contenuti in un database. Il mio problema è il seguente: Vorrei salvare questo file come temporaneo, quindi lo salvo sempre come temp.doc, ma quando per caso questo file è aperto, mi compare il il messaggio di word che il file è in sola lettura e poi il programma mi va in errore. Come posso fare a sapere se il file sul quale voglio salvare è già aperto?
Grazie a tutti
Ciao

LoryOne
21-06-2004, 19.53.40
E' naturale.
Word a differenza di Excel o Access non da la possibilità a più utenti di condividere lo stesso file (Mi pare invece che Word 2003 lo faccia, finalmente).
Più utenti significa anche lo stesso utente che apre due volte lo stesso file.
Questo perchè è Word stesso che pone un lock sul file aperto e chiunque desideri leggere il file lo può fare solo in lettura.
Devi gestire l'errore di accesso al file (l'accesso è esclusivo) segnalando all'utente di rendere disponibile il file tmp per la modifica chiudendo Word stesso.

gkcuvb
22-06-2004, 08.58.30
Ma non c'è in modo di sapere se il file è aperto senza che compaia la finestra di word dove mi dice che il file è in sola lettura? Se riuscissi a spere prima se il file è già aperto potrei salvare il mio nuovo file direttamente da un'altra parte.

LoryOne
22-06-2004, 09.31.38
Puoi provare ad aprirlo e se ti da un errore vuol dire che è già aperto.
Potresti fare una cosa così:


Function Func_ControllaFileAperto(PthFile As String)As Boolean
Dim Stato As Booelan

Stato=False
On Local Error Goto Errore
If Dir$(PthFile)<>vbNullstring Then
Open PthFile For Input As FreeFile
Reset
End If
Func_ControllaFileAperto=Stato
Exit Function
Errore:
Stato=True
Resume Next

LoryOne
22-06-2004, 09.39.14
Non funziona, come non detto.

P8257 WebMaster
22-06-2004, 09.41.28
Aprendolo semplicemente per "output" non dovrebbe dare un'access denied?

Bye :cool:

LoryOne
22-06-2004, 10.11.47
He he he, dovrebbe ! (Y) ma non è così.
Quando apri un file di Word, esso si crea un file temporaneo identificato con ~$Nomefile.doc (cedigliadollaro) che ha attributo Hidden+Archive.

Il nome del file che segue ~$ ha lunghezza variabile, nonchè nome variabile.
Se però il nome del file è piuttosto corto (non saprei dire quanto), come nel caso in esame, il nome del file non subirebbe variazioni.

Nel caso in esame dovrebbe essere ~$temp.doc

Funzione:
Funzione=Iff(Dir$(NomeFile,vbHidden+vbArchive)<>vbnullstring,true,false)

E' uno schifo, lo so però al momento non mi viene in mente nulla di meglio :D :)

gkcuvb
22-06-2004, 11.03.19
Ho provato.....ma la funzione mi ritorna sempre vero....ho dimenticato qualcosa?

P8257 WebMaster
22-06-2004, 11.28.21
Provare a cancellare il file temporaneo (utilizzando come caratteri di ricerca la tilde iniziale) e gestire l'access denied?...

Bye :cool:

LoryOne
22-06-2004, 11.59.40
Originariamente inviato da gkcuvb
Ho provato.....ma la funzione mi ritorna sempre vero....ho dimenticato qualcosa?

Prima di tutto controlla la presenza del file temporaneo.
In secondo luogo accertati della correttezza del percorso e del nome del file che imposti nel Dir$
non mi piace come soluzione ma a me funziona.

LoryOne
22-06-2004, 18.50.19
2 Soluzioni di cui la seconda decisamente più professionale, infatti si basa sull'handle del file aperto (Impossibile eseguire da VB puro)

Soluzione 1:

Function Func_FileWordAperto(sPath As String,sFile As String) As Boolean
If Right$(sPath,1)<>"\" Then sPath=sPath & "\"
If Left$(sFile,2)<>"~$" Then sFile="~$" & sFile
Func_FileWordAperto=IIf(Dir$(sPath & sFile),vbHidden+vbArchive)<>vbNullString,True,False)
End Function


Soluzione 2:

Private Const OPEN_EXISTING = 3

Private Type FILETIME
dwLowDateTime As Long
dwHighDateTime As Long
End Type

Private Type BY_HANDLE_FILE_INFORMATION
dwFileAttributes As Long
ftCreationTime As FILETIME
ftLastAccessTime As FILETIME
ftLastWriteTime As FILETIME
dwVolumeSerialNumber As Long
nFileSizeHigh As Long
nFileSizeLow As Long
nNumberOfLinks As Long
nFileIndexHigh As Long
nFileIndexLow As Long
End Type

Private Declare Function GetFileInformationByHandle Lib "kernel32" (ByVal hFile As Long, lpFileInformation As BY_HANDLE_FILE_INFORMATION) As Long
Private Declare Function CreateFile Lib "kernel32" Alias "CreateFileA" (ByVal lpFileName As String, ByVal dwDesiredAccess As Long, ByVal dwShareMode As Long, lpSecurityAttributes As Any, ByVal dwCreationDisposition As Long, ByVal dwFlagsAndAttributes As Long, ByVal hTemplateFile As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long

Function Func_FileWordAperto(sFile As String) As Byte
Dim hFile As Long, FileInfo As BY_HANDLE_FILE_INFORMATION

hFile = CreateFile(sFile, 0, 0, ByVal 0&, OPEN_EXISTING, 0, ByVal 0&)
GetFileInformationByHandle hFile, FileInfo
CloseHandle hFile
Func_FileWordAperto = FileInfo.nNumberOfLinks
End Function


La funzione ritorna 0 se il file è aperto da Word, 1 in caso contrario

gkcuvb
24-06-2004, 09.07.57
Scusate ma non sono ancora riuscite a risolvere il mio problema...

gkcuvb
24-06-2004, 09.12.44
DIvevo appunto che non sono ancora riuscita a risolvere il mio problema, questo è il codice che ho utilizzato:

WordApp.Visible = True

'apro il documento
WordApp.Documents.Open (App.Path & "\Moduli\Lista_generale.doc")
WordApp.Documents(WordApp.Documents.Count).SaveAs NomeFile

WordApp.Activate

Insomma apro un documento e vorrei salvarlo immediatamente con un altro nome per non sporcare l'originale, MA......
Utilizzando la funzione che mi avete suggerito riesco a non avere l'errore sul SaveAs, ma ho comunque un'errore quando vado ad aprire il modello, è come se mi rimanesse aperto....anche se io non lo vedo più fra i documenti aperti....
:confused:

LoryOne
24-06-2004, 09.21.32
Dunque, vediamo se ho capito il problema perchè forse non mi è chiaro.
Correggimi se sbaglio (o integra con eventuali mie dimenticanze).

Tu hai creato una base dati con Access che ti serve per creare un file di Word, in Stampa Unione, presumo.
La prima cosa da fare è creare un riferimento all'oggetto Word.Application e da qui proseguire passo-passo per interfacciarsi al Database e creare il file di Word.

Il file viene creato e chiamato temp.doc.
Il file deve poi essere modificato o ricreato completamente.
Prime di effettuare le due operazioni sopra descritte è buona norma chiudere il file per poi riaprirlo e procedere con le modifiche.

Entrmabi i codici posati funzionano perfettamente nel caso in cui il file temp.doc sia presente sull 'hard disk e sia aperto da Word.
Non può non funziopnare, l'ho testato e funziona.
Probabilmente il tuo problema dipende da qualcos'altro che però non riesco ad immaginare.
Forse ci aiuteresti maggiormante se ci spiegassi passo-passo la procedura che hai seguito fino al presentarsi dell'errore ;)

LoryOne
24-06-2004, 09.23.52
Scusa, mentre stavo scrivendo non mi sono accorto che avevi scritto qualcosa di più :)

LoryOne
24-06-2004, 09.30.54
?
Se vuoi copiare un file da un'altra parte, perchè devi utilizzare il metodo SaveAs ?
Utilizza FileCopy.

LoryOne
24-06-2004, 09.34.46
ATTENZIONE !!!!, ATTENZIONE !!!!
Non confondete VB con VBA...Non sono la stessa cosa !

gkcuvb
24-06-2004, 09.50.11
Quello che devo fare io è prendere un modello di word dove ho inserito dei segnalibri e compilare questo modulo con i dati che ho nel mio db. Il modello principale non deve essere toccato ed inpiù deve rimanere disponibile per gli altri utenti.
Sto notando una cosa strana a proposito della funzione che mi hai suggerito....pare che controlii l'esistenza del file e non il fatto che sia aperto o meno. Non so forse ho dimenticato di impostare qualcosa? Ho provato anche a riavviare la macchina per essere certa che i file che mi vengano creati da vb risultassero chiusi, ma se rilancio l'applicazione la funzione mi ritorna 1 per tutti i file creati precedentemente.
Grazie dell'interessamento

LoryOne
24-06-2004, 10.19.28
mi....pare che controlii l'esistenza del file e non il fatto che sia aperto o meno


Quando apre il file, Word ne crea una copia nascosta per tutti i file e per le modifiche apportate
La prima funzione controlla che esista ~$temp.doc che viene creato quando lo apri con Word.
La seconda deve indicare 1 se il file è chiuso e 0 se non lo è.
Entrmabe sono state testate in questo modo:

1) Mi accerto che il file di prova non sia aperto da nessuna istanza di Word
2) Creo un piccolo programmino in VB che utilizza le due funzioni e visualizza il risultato.

La prima non può sbagliare, almeno per il file ~$temp.doc
(Se il nome è differente può non funzionare per i motivi che ho già esposto)

La seconda funzione potrebbe essere fuorviata dal S.O. in uso ?
Ho Windows 98 e a me funziona.
Che versione di Word utilizzi ?
Considera che solo l'ultima versione è multiutente, quindi chiunque faccia accesso al file (che non deve essere modificato) DEVE copiarlo in locale prima di elaborarlo.

Mi spiace non aver risolto il tuo problema ma per me è solo questione di tempo...Mi piacerebbe se mi tenessi aggiornato (se vuoi, se no come non detto) sulle possibili soluzioni da te congegnate :)

NON GETTARE LA SPUGNA.

gkcuvb
24-06-2004, 10.36.05
Scusa avevo frainteso io....non avevo capito che con la funzione dovevo controllare il file temporaneo creato da word....adesso pare funzionare....GRAZIEEEE INFINITEEEE!!!!!!!!!!

LoryOne
24-06-2004, 11.19.16
Di cosa, FIGURATIIIIIIIIIIIII !!!!!!!

Toglimi una curiosità:

pare che controlii l'esistenza del file e non il fatto che sia aperto o meno. Non so forse ho dimenticato di impostare qualcosa? Ho provato anche a riavviare la macchina per essere certa che i file che mi vengano creati da vb risultassero chiusi


Che accidenti di file controllavi ?

gkcuvb
24-06-2004, 12.14.50
ehhh....controllavo temp.doc e non ~$temp.doc e ovviemente mi risultava sempre che esisteva....povera me! Forse ho bisogno di un po' di riposo???
Grazie ancora
Ciao