Newsgroup: it.comp.appl.access
Titolo: accodamento su server

Ciao a tutti,
oggi il mio problema è questo: sto usando un db su server al quale si
accede con accesso remoto.
Mi pongo la domanda: il giorno che non funziona internet come faccio?
mi rispondo: uso un db in locale e poi faccio un accodamento. Il
problema è che potrebbero accavallarsi id uguali e non mi
funzionerebbe più. Qualcuno su questo gruppo di discussione proponeva
di creare un id dipendente da client in modo che ogni pc in locale ha
sicuramente un id diverso e non ci sarebbero problemi di
accavallamento dati su server. Ma come fare? qualcuno ha qualche idea?


La butto li , perchè non  fai ricavare il nome client(ip o qualsiasi
altra cosa rilevante per il client) + numero? in questo modo avresti
pippo01.. pluto50 ect ect
Ciao


Infatti ho capito, ma non ho capito come posso fare a ricavare il nome
client...
hai qualche idea?


Copia tutto il codice dentro una maschera :
Option Compare Database
Option Explicit
'Initialisierung der API-Funktionen
Private Declare Function WSAStartup Lib "WSOCK32.DLL" (ByVal
wVersionRequired&, lpWSAData As WinSocketDataType) As Long
Private Declare Function WSACleanup Lib "WSOCK32.DLL" () As Long
Private Declare Function gethostbyname Lib "WSOCK32.DLL" (ByVal
HostName$) As Long
Private Declare Function RasEnumConnections Lib "RasApi32.DLL" Alias
"RasEnumConnectionsA" (lpRasCon As Any, lpcb As Long, lpcConnections
As Long) As Long
Private Declare Function RasGetConnectStatus Lib "RasApi32.DLL" Alias
"RasGetConnectStatusA" (ByVal hRasCon As Long, lpStatus As Any) As
Long
Private Declare Function RasEnumEntries Lib "RasApi32.DLL" Alias
"RasEnumEntriesA" (ByVal Reserved$, ByVal lpszPhonebook$,
lprasentryname As Any, lpcb As Long, lpcEntries As Long) As Long
Private Declare Function RasHangUp Lib "RasApi32.DLL" Alias
"RasHangUpA" (ByVal hRasConn As Long) As Long
Private Declare Function InternetDial Lib "wininet.dll" (ByVal
hwndParent As Long, ByVal lpszConiID As String, ByVal dwFlags As Long,
ByRef hCon As Long, ByVal dwReserved As Long) As Long
Private Declare Sub RtlMoveMemory Lib "kernel32" (hpvDest As Any,
ByVal hpvSource&, ByVal cbCopy&)
Dim ConID&
Private Type RASType
dwSize As Long
hRasCon As Long
szEntryName(256) As Byte
szDeviceType(16) As Byte
szDeviceName(32) As Byte
End Type
Private Type RASStatusType
dwSize As Long
RasConnState As Long
dwError As Long
szDeviceType(16) As Byte
szDeviceName(32) As Byte
End Type
Private Type RASENTRYNAME95
dwSize As Long
szEntryName(256) As Byte
End Type
Dim DFÜName$
Private Type HostDeType
hName As Long
hAliases As Long
hAddrType As Integer
hLength As Integer
hAddrList As Long
End Type
Private Type WinSocketDataType
wversion As Integer
wHighVersion As Integer
szDescription(0 To 256) As Byte
szSystemStatus(0 To 128) As Byte
iMaxSockets As Integer
iMaxUdpDg As Integer
lpszVendorInfo As Long
End Type
'Sub zum Beenden der Verbindung
Sub Verbindung_Beenden()
Dim x As Integer
For x = 0 To 1000
RasHangUp (x)
If DFÜStatus = False Then Exit For
Next
End Sub
'Sub zum Aufbauen der Standart Verbindung
Sub Verbindung_Aufbauen()
Dim ConName As String
InternetDial 0, ConName, 2, ConID, 0
End Sub
'Sub zum Bekommen des aktuellen DFÜ Status
Function DFÜStatus() As Boolean
Dim RAS(255) As RASType, RASStatus As RASStatusType
Dim lg&, lpcon&, Result&
RAS(0).dwSize = 412
lg = 256 * RAS(0).dwSize
Result = RasEnumConnections(RAS(0), lg, lpcon)
If lpcon = 0 Then
DFÜStatus = False
Else
RASStatus.dwSize = 160
Result = RasGetConnectStatus(RAS(0).hRasCon, RASStatus)
If RASStatus.RasConnState = &H2000 Then
DFÜStatus = True
Else
DFÜStatus = False
End If
End If
End Function
'Sub zum Bekommen der aktuellen IP
Function GetIP() As String
Dim IP$, DNS$, Host$, x As Integer
Dim GetComputer As String
Dim Result%
Dim LoBy%, HiBy%
Dim SocketData As WinSocketDataType
Result = WSAStartup(&H101, SocketData)
If Result <> 0 Then
MsgBox "Es trat ein Problem mit der winsock.dll auf.", , "Fehler"
End If
x = 2
nt:
IP = HostByName$(GetComputer, x)
If Len(IP) = 0 And x >= 0 Then
x = x - 1
GoTo nt
End If
GetIP = IP
CleanSockets
End Function
'Sub zum Bekommen der IP anhand des Hostnamens
Function HostByName(name$, Optional x% = 0) As String
Dim MemIp() As Byte
Dim y%
Dim HostDeAddress&, HostIp&
Dim IpAddress$
Dim Host As HostDeType
HostDeAddress = gethostbyname(name)
If HostDeAddress = 0 Then
HostByName = ""
Exit Function
End If
Call RtlMoveMemory(Host, HostDeAddress, LenB(Host))
For y = 0 To x
Call RtlMoveMemory(HostIp, Host.hAddrList + 4 * y, 4)
If HostIp = 0 Then
HostByName = ""
Exit Function
End If
Next y
ReDim MemIp(1 To Host.hLength)
Call RtlMoveMemory(MemIp(1), HostIp, Host.hLength)
IpAddress = ""
For y = 1 To Host.hLength
IpAddress = IpAddress & MemIp(y) & "."
Next y
HostByName = Left$(IpAddress, Len(IpAddress) - 1)
End Function
Private Sub CleanSockets()
Dim Result&
Result = WSACleanup()
If Result <> 0 Then
MsgBox "Es trat ein Problem mit der winsock.dll auf.", , "Fehler"
End If
End Sub
poi ti crei un campo testo nel mio caso testo1 e sullapertura o dove
vuoi tu
Private Sub Form_Open(Cancel As Integer)
Me.Testo1 = GetIP() 'con questo ricavi ip poi magari aggiungi &"/"+il
numero del tuo id
End Sub
ciao

Se invece vuoi il nome client .
sempre dentro una maschera:
Private Declare Function apiGetUserName Lib "advapi32.dll" Alias _
    "GetUserNameA" (ByVal lpBuffer As String, nSize As Long) As Long
Function fOSUserName() As String
' Returns the network login name
Dim lngLen As Long, lngX As Long
Dim strUserName As String
    strUserName = String$(254, 0)
    lngLen = 255
    lngX = apiGetUserName(strUserName, lngLen)
    If ( lngX > 0 ) Then
        fOSUserName = Left$(strUserName, lngLen - 1)
    Else
        fOSUserName = vbNullString
    End If
End Function
all'apertura  from o dove si vuole
me.testo1=fOSUserName()
Cmq ci sono molti post che spiegano come fare ,anche nel sito
comune.com
Ciao


Mi sa che per me è già un po' troppo complicato quello che mi proponi
anche se ti ringrazio infinitamente per la tua disponibilità.
Io adesso stavo provando così: stavo provando ad aggiungere nella
tabella Ana un campo che ho chiamato Chiave che dovrebbe diventare la
chiave primaria ed univoca. Nella maschera Anagrafica stavo cercando
di far precompilare il campo Chiave in questo modo
Chiave= IdAnagrafica And Pc su evento Prima di Inserire
IdAnagrafica è un campo contatore e Pc è il nome (inventato da me) del
pc che si inserisce automaticamente come valore predefinito es: pippo
(campo testo)
Chiave è un campo testo.
Il problema è che non mi funziona, mi dice tipo non corrispondente
In questo modo toglievo la chiave primaria in IdAna e risolvevo il mio
problema ma... sono una frana!
Adesso vado a dare un'occhiata sul sito comune...
tu hai qualche altro suggerimento?
grazie mille


Allora facciamo cosi :
in un modulo copia:
Private Declare Function apiGetUserName Lib "advapi32.dll" Alias _
    "GetUserNameA" (ByVal lpBuffer As String, nSize As Long) As Long
Public Function fOSUserName() As String
' Returns the network login name
Dim lngLen As Long, lngX As Long
Dim strUserName As String
    strUserName = String$(254, 0)
    lngLen = 255
    lngX = apiGetUserName(strUserName, lngLen)
    If (lngX > 0) Then
        fOSUserName = Left$(strUserName, lngLen - 1)
    Else
        fOSUserName = vbNullString
    End If
End Function
nella tabella hai gia aggiunto il tuo campo chiave,  aggiungilo in
maschera e lascia anche l'id originale, poi prima di aggiornare o su
aggiornamento o dove vuoi  scrivi il codice :
Me.chiave = fOSUserName & Me.ID
Ciao

 - Mostra testo citato -
Ok, grazie ci sono quasi. ti chiedo ancora questo.
L'Id originale sarà contatore ma non più chiave primara giusto?
Mi viene un dubbio: Se nella maschera inserisco il codice che mi hai
detto cosa succede consultando la maschera sul server dopo aver fatto
un accodamento dal pc? mi modifica di nuovo il valore della chiave
prendendomi il nuovo id che eventualmente si è creato?
mi spiego meglio: se nel pc inserisco una ana con id 5 la chiave
diventerà xxxx5 quando creo il record nella maschera.
nel momento in cui vado ad accodare i dati sul server, se l'Id 5 c'è
già mi trasformerà l'id del pc con un numero di contatore libero sul
server per esempio 7. La chiave rimarrà xxxx5. Ma quando apro la
maschera per consultare i dati e magari fare qualche modifica nel
record aggiornandolo mi modifica la chiave xxxx5 in xxxx7? scusa per
l'ignoranza ma non ci capisco più nulla.
Grazie ancora! ciao


L'id del server andra avanti per fatti suoi , tu devi avere se vuoi
percorrere questa strada la nuova chiave creata quella dovrebbe salvo
anomalie rimanere univoca , poi e tutto da vedere , non sappiamo se la
tua maschera ha sottomaschere e quindi devi cambiare anche il
collegamento o maschere singole .I punti da analizzare sono svariati ,
sinceramente non mi sono voluto imbattere nel problema, ma solo
aiutarti a seguire la tua strada (idea giusta o sbagliata che sia,
credo che solo smanettando si risolvano i problemi ).
Ps. se vai avanti in questa strada , cmq attento ai nomi dei
pc ...qualche nome uguale ti causerebbe problematiche  ;).
Ciao


Pardon ho risposto solo x meta alle tue domande , allora , analiziamo
la domanda:
domanda:
La chiave rimarrà xxxx5. Ma quando apro la
maschera per consultare i dati e magari fare qualche modifica nel
record aggiornandolo mi modifica la chiave xxxx5 in xxxx7?
Risposta:
si puo cambiare perche non ci sono regole impostate , io ti ho solo
suggerito come arrivare alla tua soluzione , ovvio che il codice va
modificato in base alle tue necessita , se vuoi che rimanga invariato
allora gestisci ad esempio con un if
if isnull (me.chiave)then
'Me.chiave = fOSUserName & Me.ID   '..esegue l'inserimento
else
quello che vuoi....
end if
questa e solo una delle tante soluzioni che puoi adottare ...
Ciao e buon lavoro


sì, grazie! ho preso in considerazione anche questo. Hai qualche idea
più semplice da propormi?


La prima che mi viene in mente e in caso in cui internet non funzioni
e chiamare l'assistenza adsl , dopo aver aperto il guasto , chiamare
un collega e andarsi a prendere un caffe , meglio se una collega
donna ....

 - Mostra testo citato -
Sei fantastico! Io però opterei per collega uomo dato che sono donna!
Comunque vallo dire a chi lo sta usando... io ho continuato dicendo
che gli inconvenienti possono capitare.. e se va via la luce non
possono stampare e allora io che ci posso fare... e se il pc non
parte... io che ci posso fare e possiamo continuare all'infinito!
Comunque ho quasi finito di fare la versione per questa eventualità.
Adesso se lo desidereranno si tratterà "solo" di andare ad aggiornare
le tabelle con i dati che già stanno usando...
vedremo!
comunque grazie per la tua pazienza, mi sei stato di grande aiuto.
Alla prossima


Brutta gaff se sei donna , pero hai un vantaggio , ti verra richiesto
piu spesso di prendere il caffe ehheheh...Ciao

[CUT]
Altra idea (non capisco tutta la questione della chiave primaria). Cade la
connessione, tu hai una copia in locale della tabella (anche vuota) dove
accodare i record giusto. Bene, li accodi li e sei a posto. Quando torna la
connessione, il client avvisa il server che ha dei dati, e glieli manda su
(txt, xml, mdb....come vuoi). E' il SERVER che si occupa dell'accodamento,
quindi non ci potr� MAI essere un conflitto di chiavi primarie, neanche se
tutti gli utenti inserissero insieme. Se hai bisogno di un identificativo per
sapere CHI ha scritto COSA, basta un campo in pi� con il numero di serie del
pc, il nome utente (tanto per collegarsi ce l'ha) o quello che vuoi. Oggi nn
ha pi� senso secondo me creare chiavi parlanti e campi compositi.....
-- 


Scusa un passo alla volta. Quello che mi scrivi è magnifico ma sono
desolata perchè non so come procedere.
Partiamo dall'inizio: sul server c'è il db con la base dati per es.
dati_be.mdb e un db con tabelle collegate e relative maschere che si
chiama per es. Viaggi.mdb.
Cosa devo fare? copiare i due db anche nei pc in locale con la base
dati vuota?
Poi cosa succede? il giorno che non funziona internet lavoro in
locale? come fa il server a capire che deve aggiornarsi?
come fa a non esserci conflitto con le chiavi primarie se in locale
viene usato un id già esistente sul server?
i dati della tab anagrafica sono in relazione con le iscrizioni.
Forse il tuo caso funziona se cade la linea e ti rimane la connessione
in remoto aperta?
scusa ma non riesco a capire, puoi darmi qualche dritta in più?
ringrazio infinitamente tutti e due e vi offro un caffè virtuale (_)°
°.. in attesa di una nuova connessione!

=B0.. in attesa di una nuova connessione!
La butto li (non so nulla di come è strutturato il tuo db ne tantomeno cosa
debba fare...)
Esempio: in remoto c'è un dati_be.mdb che contiene un tot di tabelle. In
locale hai viaggi.mdb che punta sul server. Bene. Se cade la connessione nn ci
puoi fare nulla, men che meno collegare in remoto.....L'unica cosa da fare che
mi venga in mente è la seguente (SE si vuol risolvere sta cosa sparando le
bombe atomiche ovviamente!). Tu i dati che ti occorrono li devi avere anche in
locale, quindi qualche cosa devi scaricarti dal server. Facciamo il caso che
ti scarichi solo parte del db quando cominci a lavorare (tutto nn avrebbe
senso...). Cade la connessione. Tu lavori con i tuoi dati localmente. Il tuo
db testa cmq la connessione ogni tot (o lo fai tramite un bottone). Se la
ritrova, avverte l'utente e poi si sincronizza. Ma chi ti dice di inviare i
dati con la chiave primaria? Tu invia i dati e fai una procedura che li
inserisce uno per uno mettendo l'opportuna chiave primaria....chiaro che
sincronizzare 2 db in cui possono esseri state cancellazioni, aggiunte,
modifiche su tutti i record non è proprio banale (tante casistiche da tenere
in considerazione) ma si fa....
-- 


Per ora mi prendo il caffe , e inizio a riflettere , analizziamo il
problema :
la tabella che tu vai ad accodare ha qualche altra relazione con altre
tabelle? o e un'unica tabella principale?
in entrambi i casi , io non credo  serva ne il sincronismo ne altro .
La mia chiave primaria ( o il mio campo univoco) me lo creo in base
agli utenti che lavorano , quindi non mi serve pormi il problema di
quale sia la chiave (contatore che mi assegna  il server) la do io in
inserimento dati .
Secondo me ti stai confondendo molto perche ti ho detto di lasciare
anche l'id nel locale (ma ti ho suggerito di farlo per non dover
crearti un contatore per assegnale un progressivo nulla di piu. e piu
facile fare nome client+id che mi da in automatico ma te lo puoi anche
generare da sola per capirci.....)
Quindi tornando al problema quando andra via la corrente , o l'adsl
non funziona o il pc non parte , o ha chiesto un permesso per andare a
fare le analisi dall'analista .. ;) si lavora in locale , la mia
chiave cmq non potra mai essere identica al server o ad altri
client ., proprio in virtu del fatto che l'assegna il client che ci
lavora.
Spero di essere stato chiaro almeno dal mio punto di vista ...se la
risposta e si il prossimo caffe lo voglio macchiato o poi divento
nervoso .. .:P
Ciao

 - Mostra testo citato -
Bene ci ho capito meno di prima... scusate.
Sul server nel mio caso c'è tutto sia base dati che l'interfaccia
Viaggi.mde.
Le tabelle di cui parlo sono Anagrafica e Iscrizioni, ovviamente
relazionate uno a molti.
Non ho scaricato Viaggi.mde in locale perchè in questo modo ci può
lavorare chiunque su qualunque pc.
Se io supponessi di copiarmi il locale la base dati già esistente e
faccio una nuova iscrizione non credo ci siano problemi di accodamento
al server al successivo accesso. Ma se devo crearmi una nuova
anagrafica e relativa iscrizione e lo fa contemporaneamente
qualcun'altro potrebbe essere che idAna= sia già stato caricato.
Infatti ho fatto le prove di accodamento su una query Anagrafica
Iscrizioni ma non mi permette di trasferire i dati perchè lo stesso id
è già presente sul server. Se trasferisco solo la tabella anagrafica
tutto ok ma l'id che in locale era 1 sul server potrebbe diventare 24
e quindi perderebbe l'integrità referenziale con idana 1 della
relativa iscrizione.
Sono di coccio? Lo so portate pazienza. Mi sa che mi serve un doppio
caffè macchiato caldo in tazza fredda!!!


Stiamo diventando nervosetti con tutto sto caffè .... :)
Allora per me ti poni un problema inutile ma davvero inutile.Il server
lavora come un client consideralo cosi , quando si accede anche il
server deve inserirsi la sua chiave , (server07 e cosi via) quando non
funziona piu nulla , quindi si e costretti a lavorare in locale , il
client assegnerà la sua chiave client01 (ad esempio) questo vale anche
per le varie relazioni , la tua tabella iscrizioni o anagrafiche
(tabelle padre/figlio) invece di avere una chiave tipo id avra la
chiave nuova client01 , server14 ect ect
quando accodi i vari dati , avrai cmq la tua relazione proprio in
virtu che le chiavi sono diverse e quindi dovresti stare tranquilla .
Spero che cosi ti sia piu chiaro , se cosi non fosse , basta caffe
passiamo alla camomilla .

 - Mostra testo citato -
Ok ho preso una bella tisanina. Quello l'ho capito e funziona grazie
ai tuoi preziosi consigli.
Quello che non riesco a capire è la proposta di Fair87 che mi dice che
il lavoro che abbiamo fatto è inutile, che non serve avere le chiavi
parlanti ecc ecc.
Ti posso offrire un orzo? o un caffè dec? grazie ciao

Ti posso offrire un orzo? o un caff=E8 dec? grazie ciao
Perchè parliamo da 2 punti di vista diversi. La chiave primaria serve al DB
non a TE!! Non serve a nulla avere chiavi composite o robe del genere xchè dai
alla primary key 2 funzioni: rendere univoco il record e dirti da chi è stato
creato o quando. X me è assurdo....visto che serve solo per la prima ragione.
Il record è un record, avrà un campo identificativo per l'utente che ci ha
lavorato magari. Faccio un esempio:
L'utente A inserisce Mario Rossi, che vive e viaggia qui e la.
L'utente B inserisce Andrea Bianchi, che vive e viaggia su e giù.
Tutti e due gli utenti mandano al server i loro dati, il server li accoda (non
centra nulla se sia collegato o tramite l'invio di file) valutando le chiavi,
la consistenza ecc ecc ecc. Il centralizzare le operazioni (client-server)
significa proprio questo. Il client fa delle cose ma l'integrità dei dati è
affidata al server, altrimenti è lavoro buttato. Ma scusate, evitando tutta
quella storia delle chiavi parlanti. Il client 1 chiede al server qual'è l'id.
Il server risponde. Il client invia una INSERT con quell'Id. Ma tra le 2
operazioni un altro client chiede la stessa cosa e il server restituisce lo
stesso Id (xchè ancora è libero), e il secondo client invia una seconda
INSERT. E adesso? chi vince? L'atomicità delle operazioni è compromessa,
perchè ci pensano i client e non il server. E poi una chiave numerica, avendo
molti dati, è più efficente di una alfanumerica. Si può fare tutto,
ovviamente, ma a mio parere ci sono alcune cose che si dovrebbero fare ed
altre no.....
-- 


OK e quindi come devo fare? perchè se io cerco di copiare i dati dalla
query in locale alla query sul server mi dice che l'Id c'è già e non
mi trasferisce niente.
La teoria l'ho capita ma la pratica no.
Con il sistema di Lolince funziona ovviamente perchè l'id non è 1 ma
1server o 1pc o quello che vuoi, nel tuo sistema continuo a non capire
come devo fare a farlo funzionare...


Scusa la mia curiosita , ma hai percaso una vpn nel gruppo dove
lavori? se si perche non passi a dei server veri e proprio (sql
express, mysql)cosi ti eviti molti casini.
Ps la tisana non mi piace molto visto che ne ho presi pochi stamane ,
ritorno al caffe....\_/) ciauzzzz

come devo fare a farlo funzionare...
Perchč pretendi di mandare su tutto (chiave compresa) e poi pretendi anche che
funzioni!!! Manda su tutto SENZA la chiave. Se unsi una qry ci sono le
maniere....Cmq, come ti dicono, il 'server' cos'č? SQL? o un mdb? se č un mdb
centralizzare ha senso un po' lato.....(file sharing e non client-server).
Puoi procedere con l'accesso sequenziale (un record alla volta). Cmq la teoria
č questa: mandi un file al server, lui se ne accorge, lo legge un record alla
volta e fai tutte le INSERT che devi. Esempio (faccio finta che mandi un file
di testo)
Trovo il file di testo
Lo apro
leggo il record
faccio INSERT 
Ripeto fino alla fine del file
cancello il file e sono pronto per il prossimo file
Se 10 client mandano 10 file lui legge uno, poi l'altro ecc ecc ecc
-- 

 - Mostra testo citato -
Allora, ci riprovo e cerco di essere molto più chiare nello spiegare
il mio problema.
Ho creato un db Viaggi.mde e Viaggi_be.mdb su un server win2008server.
Il programma deve essere usato da vari utenti con pc portatile in
posti molto diversi da loro.
L'accesso al db viaggi.mde avviene tramite connessione remota e si
lavora direttamente su server, consultazione, modifica inserimento
ecc.
In alcuni posti, al momento solo uno, è difficoltoso connettersi con
la chiavetta ad internet, non c'è nessuna altra adsl disponibile.
Ecco dove nasce il mio problema, quando l'utente è in questo maledetto
ufficio e non riesce accederea lla linea internet.
Caso 1: ascolto il consiglio di Lolince che mi propone chiavi parlanti
e funziona, va bene e non ci piove. Con questo sistema però bisogna
fare attenzione a non duplicare le anagrafiche, io in locale non so se
sul server è già presente una anagrafica, ma posso mettere il campo
codfisc univoco (su server) per evitare di accodarla. Quando io
inserisco in locale una nuova anagrafica è perchè devo fare anche una
nuova iscrizione. Nell'accodare i dati se c'è il doppione giustamente
non mi fa l'accodamento e quindi cosa succede alla mia iscrizione?
l'ho persa.
Se invece non metto il codfisc come campo univoco me la accoda senza
problemi facendomi però vedere due stesse anagrafiche con iscrizioni
vecchie da una parte e quella nuova dall'altra.
Caso 2 lascio tutto così com'è dicendo all'utente che deve andare in
quel posto maledetto di farsi una copia dal server la sera prima per
poter lavorare in locale e quando ha finito ricopia il file sul server
facendo attenzione che in quel periodo nessun altro usi la copia sul
server per evitare la perdita di dati.
Sono riuscita a spiegare bene il mio problema?