Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Usare un modulo di classe in Access.

178 views
Skip to first unread message

bari...@gmail.com

unread,
Feb 17, 2015, 4:46:56 AM2/17/15
to
All'indirizzo
https://groups.google.com/forum/?authuser=0#!searchin/it.comp.appl.access/La$20prima$20cosa$20che$20puoi$20fare$20per$20migliorare$20il$20db$20%C3%A8$20la$20seguente%7Csort:relevance/it.comp.appl.access/ycRWG5JeyTk/yAQGmIbb6tAJ

Trovo il codice proposto dall'utente BR1 che dice di usarlo per caricar più file (il post comincia con "La prima cosa che puoi fare per migliorare il db è la seguente").
Nel codice si usano delle "parolacce":
accOfficeGetFileNameInfo
bacGfniAllowMultiSelect
bacGfniInitializeView
Ho cercato in giro e ho trovato questa pagina:
http://www.tek-tips.com/viewthread.cfm?qid=273555
in cui un tale DonQuichote propone un modulo "ClsFileChooser" che appunto dichiara quella roba (e molta altra) e fornisce anche il codice per caricare un file, dove dice "You now have a filechooser:"
In effetti, mettere quel codice in un pulsante mi fa scegliere un file... niente di diverso da una cmdlg_file che ho già usato da qualche parte.
Io però voglio usare il codice di BR1, ma l'istruzione: Dim gfni As accOfficegetFileNameInfo nel codice del pulsante mi dà "Tipo non definito".
In effetti le dichiarazioni di ClsFileChooser sono Private, e allora come le uso? Sono vagamente consapevole che l'istruzione: with new ClsFilechooser abbia a che farci, ma più in là non so andare.

Posso suscitare la comprensione di qualche esperto che diradi un po' la nebbia?
Grazie
Riccardo Baldinotti

bari...@gmail.com

unread,
Feb 17, 2015, 9:29:11 AM2/17/15
to
E poi trovo ancora questa roba, http://help.lockergnome.com/office2/Prompt-file-location--ftopict26158.html e anche qui copio tutto in un modulo ma ottengo solo tipi non definiti e parametri non facoltativi...

@Alex

unread,
Feb 17, 2015, 9:50:15 AM2/17/15
to
Invece di fare tutto questo pippone... non fai prima a spiegare cosa devi fare...?
Mi sono dovuto rileggere un 3D di 10 anni fa in cui già rompevo le scatole allora ed ero 10 anni più giovane...

Saluti
@Alex

Alessandro Cara

unread,
Feb 17, 2015, 10:17:44 AM2/17/15
to
Il 17/02/2015 15:50, @Alex ha scritto:
> Invece di fare tutto questo pippone... non fai prima a spiegare cosa devi fare...?
> Mi sono dovuto rileggere un 3D di 10 anni fa in cui già rompevo le scatole allora ed ero 10 anni più giovane...

Adesso rompi le scatole con maggiore esperienza? ;-)

--
ac (x=y-1)
Aborro il Killfile
(La violenza e' l'ultimo rifugio degli incapaci -Salvor Hardin-)

---
Questa e-mail è stata controllata per individuare virus con Avast antivirus.
http://www.avast.com

bari...@gmail.com

unread,
Feb 17, 2015, 10:24:56 AM2/17/15
to
Il giorno martedì 17 febbraio 2015 15:50:15 UTC+1, @Alex ha scritto:
> Invece di fare tutto questo pippone... non fai prima a spiegare cosa devi fare...?
> Mi sono dovuto rileggere un 3D di 10 anni fa in cui già rompevo le scatole allora ed ero 10 anni più giovane...

Dunque, quel codice di BR1 dovrebbe permettermi di scegliere più file da una cartella e poi ci faccio delle cose: scrivere nome e data di modifica in una tabella, copiarli in una sottocartella...

Quindi l'ho messo su click di un pulsante, però mi dice che non ho definito accOfficeGetFileNameInfo. Vero, non l'ho definito né so come fare.

A quel punto sono andato in giro a cercare esempi e mi sono impantanato. E sono invecchiato 10 anni nel fisico e 30 nell'autostima :-(

Grazie
Riccardo Baldinotti

Alessandro Cara

unread,
Feb 17, 2015, 1:17:16 PM2/17/15
to
che ne dici di questo link?
http://www.tek-tips.com/viewthread.cfm?qid=273555

a quanto pare accOfficeGetFileNameInfo non e' una classe ma una
struttura (type)
E' quello che sta li che hai copiato? Compare il donchisciotte che hai
citato. La struttura e' privata perche' ci sono funzioni pubbliche della
classe (quella che ti chiede di definire) che la gestiscono. Non devi
definirla fuori e soprattutto non e' una classe.

bari...@gmail.com

unread,
Feb 18, 2015, 5:24:13 AM2/18/15
to
Il giorno martedì 17 febbraio 2015 19:17:16 UTC+1, Alessandro Cara ha scritto:
> >
> che ne dici di questo link?
> http://www.tek-tips.com/viewthread.cfm?qid=273555

è proprio la pagina che citavo, quella dove ho trovato definito la struttura.


> a quanto pare accOfficeGetFileNameInfo non e' una classe ma una
> struttura (type)
> E' quello che sta li che hai copiato? Compare il donchisciotte che hai
> citato. La struttura e' privata perche' ci sono funzioni pubbliche della
> classe (quella che ti chiede di definire) che la gestiscono. Non devi
> definirla fuori e soprattutto non e' una classe.
>

Chiedo scusa. Anni fa, dopo aver letto decinaia e decinaia di pagine su ereditarietà, polimorfismo e incapsulamento nel tentativo di imparare Delphi, decisi:
- che non ce l'avrei fatta,
- che gli americani avevano modi raffinati di descrivere l'acqua calda.
Ora è forse giunto il momento di pentirmi...

Perciò, col capo cosparso di cenere, faccio domande:
Io mi trovo col modulo di una maschera dove ho copiato il codice dell'utente BR1 che citavo, dove dice:
Dim gfni As accOfficegetFileNameInfo
però ottengo un errore perché quel codice non mi trova il tipo.
Se ho ben capito, dovrei spiegare al codice come trovarlo e allora dovrei "caricare" le funzioni che lo gestiscono. E qui nasce il mio interesse per quelle istruzioni:
With New ClsFileChooser
.setDirectory "D:\Documenti generali"
' ... any other things you want to set first ...
stri = .getFileNameForOpen
If stri <> "" Then
SaveNewRecC (stri)
Me.Requery
End If
End With

che trovo nella pagina che hai citato. Con quelle riesco a selezionare un file per farne quello che voglio, ma mi resta nel gozzo la voglia di provare il codice di BR1 per selezionare più file.

Spero di essere stato più chiaro.
Grazie
Riccardo Baldinotti

Alessandro Cara

unread,
Feb 18, 2015, 7:20:32 AM2/18/15
to
Il 18/02/2015 11:24, bari...@gmail.com ha scritto:
> Il giorno martedì 17 febbraio 2015 19:17:16 UTC+1, Alessandro Cara ha scritto:
>>>
>> che ne dici di questo link?
>> http://www.tek-tips.com/viewthread.cfm?qid=273555
>
> è proprio la pagina che citavo, quella dove ho trovato definito la struttura.
>
>
>> a quanto pare accOfficeGetFileNameInfo non e' una classe ma una
>> struttura (type)
>> E' quello che sta li che hai copiato? Compare il donchisciotte che hai
>> citato. La struttura e' privata perche' ci sono funzioni pubbliche della
>> classe (quella che ti chiede di definire) che la gestiscono. Non devi
>> definirla fuori e soprattutto non e' una classe.
>>
>
> Chiedo scusa. Anni fa, dopo aver letto decinaia e decinaia di pagine su ereditarietà, polimorfismo e incapsulamento nel tentativo di imparare Delphi, decisi:
> - che non ce l'avrei fatta,
> - che gli americani avevano modi raffinati di descrivere l'acqua calda.
> Ora è forse giunto il momento di pentirmi...
>
> Perciò, col capo cosparso di cenere, faccio domande:

Lascia sta che poi sporchi il pavimento ;-)

> Io mi trovo col modulo di una maschera dove ho copiato il codice dell'utente BR1 che citavo, dove dice:
> Dim gfni As accOfficegetFileNameInfo


non ho compreso quale sia questo codice.
Mi pare di capire che il codice a cui fai riferimento non e' quello del
link.
questo pezzo qui e' quello che definisce la struttura

Private Type accOfficegetFileNameInfo
hwndOwner As Long
strAppName As String * 255
strDlgTitle As String * 255
strOpenTitle As String * 255
strFile As String * 4096
strInitialDir As String * 255
strFilter As String * 255
lngFilterIndex As Long
lngView As Long
lngFlags As Long
End Type

se vuoi usarla fuori dalla classe la devi copiare da qualche parte in
modo che sia "visibile" quando la /ridefinisci/
i.e.
Dim gfni As accOfficegetFileNameInfo

quella struttura serve a questa funzione
Private Declare Function accOfficegetFileName Lib "msaccess.exe" Alias
"#56" (gfni As accOfficegetFileNameInfo, ByVal fOpen As Integer) As Long
'Internal function in MS-Access to show the fileopen dialog, with ftp
locations and everything.

la puoi chiamare anche /giuseppe/ ma deve essere un /giuseppe/ di quel
formato.


Entrambe sono di tipo /privato/ cio' significa che la classe ha i metodi
pubblici per variare le proprieta' della struttura e per chiamare la "#56"

cosa ci fa poi l' /utente/ br1 con questo codice?
Perche' ha bisogno di /ridefinirla/ ?

> però ottengo un errore perché quel codice non mi trova il tipo.
> Se ho ben capito, dovrei spiegare al codice come trovarlo e allora dovrei "caricare" le funzioni che lo gestiscono. E qui nasce il mio interesse per quelle istruzioni:
> With New ClsFileChooser
> .setDirectory "D:\Documenti generali"
> ' ... any other things you want to set first ...
> stri = .getFileNameForOpen
> If stri <> "" Then
> SaveNewRecC (stri)
> Me.Requery
> End If
> End With
>


bari...@gmail.com

unread,
Feb 18, 2015, 8:08:50 AM2/18/15
to
Il giorno mercoledì 18 febbraio 2015 13:20:32 UTC+1, Alessandro Cara ha scritto:

> > Io mi trovo col modulo di una maschera dove ho copiato il codice dell'utente BR1 che citavo, dove dice:
> > Dim gfni As accOfficegetFileNameInfo
>
>
> non ho compreso quale sia questo codice.

Il codice nel link che citavo nel mio primo messaggio:
https://groups.google.com/forum/?authuser=0#!searchin/it.comp.appl.access/La$20prima$20cosa$20che$20puoi$20fare$20per$20migliorare$20il$20db$20%C3%A8$20la$20seguente%7Csort:relevance/it.comp.appl.access/ycRWG5JeyTk/yAQGmIbb6tAJ

nel post di un certo BR1 che comincia con "La prima cosa che puoi fare per migliorare il db è la seguente"

> se vuoi usarla fuori dalla classe la devi copiare da qualche parte in
> modo che sia "visibile" quando la /ridefinisci/
> i.e.
> Dim gfni As accOfficegetFileNameInfo
>
E in effetti quell'istruzione c'è. Io ho copiato supinamente il codice in un pulsante, ed è proprio quell'istruzione a generare l'errore "Tipo non definito".


> quella struttura serve a questa funzione
> Private Declare Function accOfficegetFileName Lib "msaccess.exe" Alias
> "#56" (gfni As accOfficegetFileNameInfo, ByVal fOpen As Integer) As Long
> 'Internal function in MS-Access to show the fileopen dialog, with ftp
> locations and everything.
>
Al colmo della disperazione, ho copiato la Declare che citi nel modulo della maschera contenente il pulsante, ma così dava errore la accOfficegetFileNameInfo, allora ci ho copiato anche questa definizione e allora mi dava errore questo:
If officegetFileName(gfni, -1) = 0 Then
e ho copiato anche questa Function, poi anche la Function trimFixedString.
A questo punto il Debug ha smesso di protestare, ho cliccato sul pulsante e (magia, magia!) ho potuto caricare simultaneamente tre (!!!) file e avviare la routine che doveva trattarne i dati.

Insomma, senza ancora aver capito molto, almeno credo di avere capito questo:
il modulo di classe è il mio supermercato, scelgo i prodotti e li metto nel carrello finché la cassiera (pardon, il debug) è contenta.

Ah, già, ho anche capito cosa intendevi con "la devi copiare da qualche parte"!

Questo però è un po' diverso da ciò che pensavo fosse un modulo di classe... io insistevo nel fare una cosa tipo:
Dim qualcosa As New ClsFileChooser
e pensavo di avere così a disposizione tutti i prodotti del supermercato.

Grazie, Stentatamente, ma vo' facendomi strada, grazie a voialtri guru.
ccardo Baldinotti

Alessandro Cara

unread,
Feb 18, 2015, 8:54:07 AM2/18/15
to
Il 18/02/2015 14:08, bari...@gmail.com ha scritto:

> Questo però è un po' diverso da ciò che pensavo fosse un modulo di classe... io insistevo nel fare una cosa tipo:
> Dim qualcosa As New ClsFileChooser
> e pensavo di avere così a disposizione tutti i prodotti del supermercato.

Esatto dovrebbe essere cosi'
Comunque a tempo perso daro' una occhiata a quel link che hai scritto.
Il codice di donchisciotte dovrebbe essere sufficiente, non comprendo
perche' questo br1 lo ha manomesso.
Al limite, forse, poteva essere necessario qualche piccolo aggiustamento
all'interno della classe non vedo perche' sei stato costretto a fare
quello che hai fatto.
(sempre che abbia compreso quello che hai fatto ;-) )


Comunque un modulo di classe e' come se fosse un programma di cui puoi
farne quante copie vuoi.
Facendo una forzatura.
Immagina che la tua applicazione sia attivata da n terminali diversi.
Di fatto ogni terminale usa una copia della tua /classe/ (attenzione e'
una analogia) ed ha a disposizione tutte le possibilita' che la tua
applicazione ha.
Quelle e non altre. Se vuoi qualcosa di piu' devi modificare la
applicazione e /automaticamente/ tutti vedono poi le nuove caratteristiche.

bari...@gmail.com

unread,
Feb 19, 2015, 7:47:38 AM2/19/15
to
Il giorno mercoledì 18 febbraio 2015 14:54:07 UTC+1, Alessandro Cara ha scritto:
>
> > Questo però è un po' diverso da ciò che pensavo fosse un modulo di classe... io insistevo nel fare una cosa tipo:
> > Dim qualcosa As New ClsFileChooser
> > e pensavo di avere così a disposizione tutti i prodotti del supermercato.
>
> Esatto dovrebbe essere cosi'

Allora, senza essermi copiato nulla da ClsFileChooser al mio modulo della maschera, io ho provato a scrivere:

Set prova = New ClsFileChooser
Dim gfni As prova.accOfficegetFileNameInfo

ma ottengo errore "Tipo non definito" e mi si evidenzia la riga da "gfni" in avanti.
Senza la Set, invece, e scrivendo accOfficegetFileNameInfo senza "prova.", mi si evidenziava solo quell'ultima parola.

Bò.

Alessandro Cara

unread,
Feb 19, 2015, 12:34:38 PM2/19/15
to
non e' bo'
accOfficegetFileNameInfo
questa e' /private/ e non la vedrai mia.
Vedi che succede se la trasformi in public
E comunque ho guardato il link (l'altro)
A parte le solite menate di @Alex ;-)
Di fatto devi modificare la proprieta' .lngflags di accOfficegetFileNameInfo
e' uno dei parametri del metodo getFileName che e' compreso nel codice:
getfilename(.......flags:=quello che e'.....)

il codice originale e' questo:
Public Function getFileName(Optional ByVal initialDirectory As String =
"", Optional ByVal fileName As String = "", _
Optional ByVal DialogTitle As String =
"Select file", Optional ByVal openButtonLabel As String = "&Select", _
Optional ByVal filter As String = "All
files (*.*)", Optional ByVal filterIndex As Long = 0, _
Optional ByVal appName = "", Optional ByVal
view As Long = 3, _
Optional ByVal flags As Long = &H41,
Optional ByVal selectExisting As Boolean = True) As String
Const SUCCESSFUL As Long = 0

come vedi possono essere passati tutti i valori che riguardano la
struttura proprio per modificare il comportamento
se non si passa /flags/ viene preso il default che e' &H41 che
presumibilmente vorra' dire un solo file alla volta.
Ogni parametro fa riferimento ad uno dei campi della type (tranne l'hwnd
che non dovrebbe servire)

Quello che fa br1 e' la classica /porcata/ che funziona.

bari...@gmail.com

unread,
Feb 20, 2015, 5:11:44 AM2/20/15
to
Il giorno giovedì 19 febbraio 2015 18:34:38 UTC+1, Alessandro Cara ha scritto:


> accOfficegetFileNameInfo
> questa e' /private/ e non la vedrai mia.
> Vedi che succede se la trasformi in public
Ho provato e, come in tentativi simili, ho ottenuto "Impossibile definire come pubblico un tipo definito dall'utente all'interno di un modulo di oggetto."



> se non si passa /flags/ viene preso il default che e' &H41 che
> presumibilmente vorra' dire un solo file alla volta.
Ho girato tutto il ClsFileChooser e ho trovato quel lngFlags in vari contesti, gli si passa un'altra variabile 'flags', lo si definisce nel Type gfni, eccetera.
Mi riesce impossibile capire un pezzo di codice che fa riferimento a un altro pezzo, che fa riferimento a un altro pezzo, che usa una variabile definita da un'altra parte... e poi parlavano di programmazione a spaghetti per il buon vecchio GoTo!

Per di più non so cosa mettere al posto di &H41 e il fatto che rappresenti l'Unicode di 'A' non mi pare significativo. Ho girato per trovare esempi ma ci sono tante definizioni della getFileName, diverse fra loro.

Ho fatto tentativi di incorporare i componenti di ClsFileChooser con roba tipo:
Dim prova as ClsFileChooser
Set prova=New ClsFileChooser
E altre amenità senza effetto.
Mi sto addentrando in un ginepraio in cui, a causa della mia ignoranza, posso solo perdermi. In essa rimarrò.

[OT] come mai usi l'apostrofo per le lettere accentate? Usi un Commodore64, uno ZX Spectrum? (te beato...) :-)

Grazie
Riccardo Baldinotti

Alessandro Cara

unread,
Feb 20, 2015, 7:04:31 AM2/20/15
to
Il 20/02/2015 11:11, bari...@gmail.com ha scritto:
> Il giorno giovedì 19 febbraio 2015 18:34:38 UTC+1, Alessandro Cara ha scritto:
>
>
>> accOfficegetFileNameInfo
>> questa e' /private/ e non la vedrai mia.
>> Vedi che succede se la trasformi in public
> Ho provato e, come in tentativi simili, ho ottenuto "Impossibile definire come pubblico un tipo definito dall'utente all'interno di un modulo di oggetto."
>
>
>
>> se non si passa /flags/ viene preso il default che e' &H41 che
>> presumibilmente vorra' dire un solo file alla volta.
> Ho girato tutto il ClsFileChooser e ho trovato quel lngFlags in vari contesti, gli si passa un'altra variabile 'flags', lo si definisce nel Type gfni, eccetera.
> Mi riesce impossibile capire un pezzo di codice che fa riferimento a un altro pezzo, che fa riferimento a un altro pezzo, che usa una variabile definita da un'altra parte... e poi parlavano di programmazione a spaghetti per il buon vecchio GoTo!

i goto erano una cosa chiara. Piu' complicato quando si usavano
istruzioni che modificavano l'indirizzo di salto.
Il codice di donchisciotte mi sembra abbastanza ben organizzato.

>
> Per di più non so cosa mettere al posto di &H41 e il fatto che rappresenti l'Unicode di 'A' non mi pare significativo. Ho girato per trovare esempi ma ci sono tante definizioni della getFileName, diverse fra loro.
&H41 e' 0100 0001 in binario (65 decimale e quindi A). Qui sono i bit
on/off che contano.

br1 fa questo
lngFlags = lngFlags Or bacGfniAllowMultiSelect
e sufficiente vedere quale bit mette in on bacGfniAllowMultiSelect

a occhio potrebbe essere questa
Public Function FLAGALLOWMULTISELECT() As Long
FLAGALLOWMULTISELECT = 8
End Function

bari...@gmail.com

unread,
Feb 20, 2015, 8:19:25 AM2/20/15
to
Il giorno venerdì 20 febbraio 2015 13:04:31 UTC+1, Alessandro Cara ha scritto:

>
> i goto erano una cosa chiara. Piu' complicato quando si usavano
> istruzioni che modificavano l'indirizzo di salto.

eh eh, ci provai anch'io col processore dello Spectrum, quelle istruzioni multibyte erano una tentazione irresistibile.

> Il codice di donchisciotte mi sembra abbastanza ben organizzato.

Lo so, sono io che fatico perché non ho l'abitudine. Sai, quelli che non hanno mai studiato?

> &H41 e' 0100 0001 in binario (65 decimale e quindi A). Qui sono i bit
> on/off che contano.
>
> br1 fa questo
> lngFlags = lngFlags Or bacGfniAllowMultiSelect
> e sufficiente vedere quale bit mette in on bacGfniAllowMultiSelect
>
> a occhio potrebbe essere questa
> Public Function FLAGALLOWMULTISELECT() As Long
> FLAGALLOWMULTISELECT = 8
> End Function

Infatti questa riga
Const bacGfniAllowMultiSelect = &H8 ' Allow multiple-selection?
che ho copiato anch'essa nel mio modulo dà lo stesso valore.
Allora &H41 or &H08 dà &H49

Quindi potrei metterlo qui:
Public Function getFileName(Optional ByVal initialDirectory As String = "", Optional ByVal fileName As String = "", _
Optional ByVal DialogTitle As String = "Select file", Optional ByVal openButtonLabel As String = "&Select", _
Optional ByVal filter As String = "All files (*.*)", Optional ByVal filterIndex As Long = 0, _
Optional ByVal appName = "", Optional ByVal view As Long = 3, _
Optional ByVal flags As Long = &H41, Optional ByVal selectExisting As Boolean = True) As String

nel valore di flags e usare il "file chooser" di donchisciotte...
Mo' provo (pant pant).

Grazie, soprattutto per la pazienza.
Riccardo Baldinotti

0 new messages