Newsgroup: it.comp.appl.access
Titolo: Per sapere le il db è già in uso?

Visto che ho dei colleghi "pasticcioni" che aprono un db A97, poi lo
riducono a icona per fare un'altra cosa, poi senza avvedersi troppo lo
riaprono e riaccedono allo stesso record e vanno in panne all'avviso di
modifica contemporanea, come posso controllare all'apertura se il db è già
aperto, cioè spero di essermi spiegato :-)).
saluti a tutti

 wrote in message
news:ZC018.2201$WS2....@news1.tin.it...

Fai una bella Tabella che registra gli utenti che fanno il Login...!
Ovviamente cancelli dalla Tabella l'utente alla chiusura....!!
Alessandro.(@Alex)
-- 
Posted via Mailgate.ORG Server - 
http://www.Mailgate.ORG

 ha scritto nel messaggio
news:ZC018.2201$WS2....@news1.tin.it...

E' possibile, via Api, controllare che non vi siano altre istanze della
stessa applicazione su di un PC. Quindi dovresti riuscire ad evitare di fare
aprire trentamila copie dello stesso programma su di un solo pc.
Per quanto riguarda invece il fatto che continuino a bloccare un record,
anche se ridotto ad icona, ci sono diverse strade: personalmente ti
consiglierei, tramite una maschera nascosta, di implementare un time-out di
inatività, in sostanza, per esempio, se per cinque minuti l'utente non
utilizza più l'applicativo il programma si chiude automaticamente.
Se ti servono degli esempi di codice per implementare queste due funzioni
fammi un fischio.
Ciao
        Roberto Marengo

         Roberto Marengo
Io mi auguro non si tratti di più istanze dello stesso DB, ma caso mai
di un BE condiviso al quale hanno accesso gli utenti tramite vari FE....!!!
Se on è così io consiglio prima di rivedere la progettazione del DB
e scomporlo in FE<--->BE, poi il metodo migliore è quello di registrare
in tabella l'accesso.
In ogni momento sai chi è connesso da quanto tempo e se non ha operato
fare il LOGOUT....!!!


 saluti a tutti
Un' altra possibilitą č leggere il File TuoDatabase.Ldb che registra
in formato testo Utente e Macchina....!!


 Alessandro.(@Alex)
Ho qualche perplessità ad implementare la tecnica che descrivi tu in una
base dati Access. Infatti non essendo un RDBMS in caso si pianti
l'applicativo con un errore irreversibile di Access (leggi dr. Watson), ti
resterebbe marcato come Loggato anche l'utente che ha generato il crash.
Dovrebbe quindi intervenire l'equivalente un DBA per sistemare gli
archivi....
Ciaoo



Se trattasi di un DB non diviso e condiviso in rete e
se ti interessa che ci si lavori su uno x volta, puoi anche crearti un
batch che ti lancia l'mdb e che contemporaneamente:
- verifica se esiste nella stessa directory l'ldb (puoi anche fargli
leggere il nome macchina e lo username)
oppure
se nessuno è connesso, crea un file di log (con il nome macchina e
l'utente, e lo cancella all'uscita)
se qualcuno è connesso, legge il file di log e avvisa che il programma
è utilizzato da 'nome macchina', 'utente'.
Volendo poi con un net send sulla macchina.....A
Cicciooo.....Mollaaaa!
Pino

 Ciaoo
Hai tutte le ragioni del caso, ma fare accesso in un numero superiore
a 2 di utenti su un DB ACCESS è già di per se una TRAPPOLA da evitare.
Il Vantaggio del FE--BE in questo caso, che credo non sia un'applicativo
professionale(sarebbe SQLSERVER o altra piattaforma per multiutenza) avrebbe
il vantaggio di gestire agevolmente eventuali modifiche/aggiornamenti del FE. 
Però giustamente come dici tu ci sono alcuni inconvenienti da evitare...!
Ciao.


Gulp !! Quante risposte.
Innanzi tutto grazie e scusate se di fronte a tanta solerzia posso
rispondervi solo ora, dunque:
quello da "bloccare" è un file FE.mde che lavora con tre BE, infatti il
sistema è costituito da lan con un servente WNT e una decina di client
alcuni W95 ed altri WNT, premetto che i generalmente i client che lavorano
contemporaneamente non sono + di 4 e che ogni utente crea e ed aggiorna dei
propri record su uno dei BE attingendo però dei dati comuni dagli altri due
BE che vengono periodicamente aggiornati solo dal sottoscritto
(all'occorrenza con un artificio il FE  segnala il blocco tra 1' e poi
Quit).
L'idea del campo o file che memorizza open e close sarebbe valida, ma come
la mettiamo con crash neanche tanto rari se consideriamo di avere a che fare
con chi apre al'infinito senza chiudere e poi quando il sistema è in tilt
sovente fa il reset del pc?
In tal caso anche l'idb rimane.
Mi pare quindi che la strada migliore (o lunica?) sia quella della verifica
tramite API che però io non conosco, quindi pregherei Roberto Marengo di
suggerirmi come procedere.
Ciao

 Ciao
Io non credo.
Se hai WNT con SQL SERVER abbandona ACCESS come BE e usa SQL SERVER.


 Alessandro.(@Alex)
In astratto SQL Server è sicuramente più solido, però per 4 accessi
contemporanei, salvo carichi di lavoro immensi, può bastare Access. Tutto,
come sempre nella vita, dipende dal budget!!!
Personalmente ho numerosi progetti, anche più pesanti di quello descritto,
che lavorano sotto Access.
Ciaooo
        Roberto

 Ciao
Ecco qua dunque: metti il codice sotto riportato in un modulo, personalizza
il messaggio di attenzione (in fondo) in base al nome del tuo programma, e
richiama la funzione  winCheckMultipleInstances() all'apertura del database.
Fammi sapere se hai problemi.
Ciaoo
        Roberto
'******************** Code Start ********************
Option Compare Database
Option Explicit
Private Const cMaxBuffer = 255
Private Declare Function apiGetClassName Lib "user32" _
  Alias "GetClassNameA" _
  (ByVal hwnd As Long, _
  ByVal lpClassName As String, _
  ByVal nMaxCount As Long) _
  As Long
Private Declare Function apiGetDesktopWindow Lib "user32" _
  Alias "GetDesktopWindow" _
  () As Long
Private Declare Function apiGetWindow Lib "user32" _
  Alias "GetWindow" _
  (ByVal hwnd As Long, _
  ByVal wCmd As Long) _
  As Long
Private Const GW_CHILD = 5
Private Const GW_HWNDNEXT = 2
Private Declare Function apiGetWindowText Lib "user32" _
  Alias "GetWindowTextA" _
  (ByVal hwnd As Long, _
  ByVal lpString As String, _
  ByVal aint As Long) _
  As Long
Private Declare Function apiSetActiveWindow Lib "user32" _
  Alias "SetActiveWindow" _
  (ByVal hwnd As Long) _
  As Long
Private Declare Function apiIsIconic Lib "user32" _
  Alias "IsIconic" _
  (ByVal hwnd As Long) _
  As Long
Private Declare Function apiShowWindowAsync Lib "user32" _
  Alias "ShowWindowAsync" _
  (ByVal hwnd As Long, _
  ByVal nCmdShow As Long) _
  As Long
Private Const SW_SHOW = 5
Private Const SW_RESTORE = 9
Public Function winGetClassName(hwnd As Long) As String
Dim sBuffer As String, iLen As Integer
  sBuffer = String$(cMaxBuffer - 1, 0)
  iLen = apiGetClassName(hwnd, sBuffer, cMaxBuffer)
  If iLen > 0 Then
    winGetClassName = Left$(sBuffer, iLen)
  End If
End Function
Public Function winGetTitle(hwnd As Long) As String
Dim sBuffer As String, iLen As Integer
  sBuffer = String$(cMaxBuffer - 1, 0)
  iLen = apiGetWindowText(hwnd, sBuffer, cMaxBuffer)
  If iLen > 0 Then
    winGetTitle = Left$(sBuffer, iLen)
  End If
End Function
Public Function winGetHWndDB(Optional hWndApp As Long) As Long
Dim hwnd As Long
winGetHWndDB = 0
If hWndApp <> 0 Then
  If winGetClassName(hWndApp) <> "OMain" Then Exit Function
End If
hwnd = winGetHWndMDI(hWndApp)
If hwnd = 0 Then Exit Function
hwnd = apiGetWindow(hwnd, GW_CHILD)
Do Until hwnd = 0
  If winGetClassName(hwnd) = "ODb" Then
    winGetHWndDB = hwnd
    Exit Do
  End If
  hwnd = apiGetWindow(hwnd, GW_HWNDNEXT)
Loop
End Function
Public Function winGetHWndMDI(Optional hWndApp As Long) As Long
Dim hwnd As Long
winGetHWndMDI = 0
If hWndApp = 0 Then hWndApp = Application.hWndAccessApp
hwnd = apiGetWindow(hWndApp, GW_CHILD)
Do Until hwnd = 0
  If winGetClassName(hwnd) = "MDIClient" Then
    winGetHWndMDI = hwnd
    Exit Do
  End If
  hwnd = apiGetWindow(hwnd, GW_HWNDNEXT)
Loop
End Function
Public Function winCheckMultipleInstances(Optional fConfirm As Boolean =
True) As Boolean
Dim fSwitch As Boolean, sMyCaption As String
Dim hWndApp As Long, hWndDb As Long
On Error GoTo ProcErr
  sMyCaption = winGetTitle(winGetHWndDB())
  hWndApp = apiGetWindow(apiGetDesktopWindow(), GW_CHILD)
  Do Until hWndApp = 0
    If hWndApp <> Application.hWndAccessApp Then
      hWndDb = winGetHWndDB(hWndApp)
      If hWndDb <> 0 Then
        If sMyCaption = winGetTitle(hWndDb) Then Exit Do
      End If
    End If
    hWndApp = apiGetWindow(hWndApp, GW_HWNDNEXT)
  Loop
  If hWndApp = 0 Then Exit Function
  If fConfirm Then
    MsgBox "Attenzione è già presente una copia aperta di WinDistretti, non
è consentito l'uso simultaneo di più copie di WinDistretti sulla stessa
macchina", vbCritical
  End If
  apiSetActiveWindow hWndApp
  If apiIsIconic(hWndApp) Then
    apiShowWindowAsync hWndApp, SW_RESTORE
  Else
    apiShowWindowAsync hWndApp, SW_SHOW
  End If
  Application.Quit
ProcEnd:
  Exit Function
ProcErr:
  MsgBox Err.Description
  Resume ProcEnd
End Function
'******************** Code End ********************

 Fammi sapere se hai problemi.
Nessun problema, funziona alla perfezione, posso solo aggiungere che ti sono
veramente grato.
Ciao
          Pasqualino