Newsgroup: it.comp.lang.visual-basic
Titolo: [?] Eseguire uno "shift" dei dati, su un DB Access.

Ciao a tutti !!
Mi trovo a dover far apparire un grafico generato da 1200 valori registrati
da un apparecchiatura esterna.
Viene fatto un sondaggio ogni 3 secondi.
Per mostrare il grafico in "movimento" , cioe' che mostra dal valore reale
aī 30 minuti precedenti, proseguo in questo modo :
Salvo su un DB in formato Access i dati in arrivo.
Al raggiungimento del 1200esimo dato, cancello il primo e ne aggiungo uno in
fondo.
E cosi' via...
Quindi...in teoria quando elimino il primo dato e ne aggiungo uno in fondo,
tutto va bene, perche' simulo uno shift dei dati.
Solo che.. non va proprio cosi' in realta'...
La routine che esegue il salvataggio/cancellazione dal db e' controllata da
un timer che genera un evento ogni 3 secondi, ma dopo aver cancellato il
dato.. non scrive il successivo all'ultima posizione, ma a una posizione
casuale nel db. Ho pensato che potesse dipendere dal fatto che il timer
blocca l'esecuzione del salvataggio prima che il DB venga aggiornato.. ma
non dovrebbe essere quello....
Mi chiedevo.. ci sara' un modo piu' rapido di far scorrere i dati... cioe'
che venga cancellato il primo e ne venga aggiunto un altro ?
Oppure mi conviene rinunciare al DB e lavorare con un array ? (sempre che si
riesca a fare un array di 1200 valori)
Cmq anche con un array mi troverei ad affrontare la lentezza di spostare
tutti i valori contenuti, alla posizione precedente, per far spazio
all'ultimo.
Argh.. spero di essere riuscito a spiegare il mio problema.. e confido in
voi per un buon consiglio :-))
Ciao e grazie, DaVe
P.S : uso VB5 + SP3

Strano, ma forse non ho capito bene.
Hai impostato una chiava primaria di autoincremento nella tabella ?

 fondo.
Lascia perdere il DB e creati una lista circolare.
Se i file devono essere salvati su disco, usa un normale file ad accesso
casuale (guardati l'help con parola chiave "OPEN" se hai problemi),
altrimenti usa un array.
Non ti preoccupare dello spazio: un array di 1200 valori numerici occupa
meno di 5Kb. Se sono double o currency 10Kb.
Ti salva in una variabile (o come primo elemento del file ad accesso
casuale, nel caso dovessi volerlo usare) il puntatore al primo record
corrente. Il record da sostituire col nuovo valore č dato da:
iif(PrimoRecord>1,PrimoRecord-1,1200)
Poi per ridisegnare il tuo grafico parti dall'elemento PrimoRecord e vai
avanti fino a 1200, poi ricominci da 1 vai avanti fino a PrimoRecord-1.
Tutto chiaro?
Ciao
*Roby*

E cosi' via...
[SNIP]
Segui il consiglio di Roberto e passa tranquillamente ad un array; se vuoi
shiftarlo rapidamente puoi provare cosi':
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _
 (lpvDest As Any, lpvSource As Any, ByVal cbCopy As Long)
Private Declare Sub ZeroMemory Lib "kernel32" Alias "RtlZeroMemory" _
 (dest As Any, ByVal numbytes As Long)
Sub ShiftArray(arValues() As <TipoDati>, Index As Long)
Dim ItemLen As Long, ItemCount As Long
'stabiliamo l'occupazione in bytes del singolo elemento
'e il numero di elementi
ItemLen = Len(arValues(Index))
'questo nel nel caso di un array "classico" 0..n,altrimenti modificare di
conseguenza
ItemCount = UBound(arValues) + 1
'shiftiamo a sinistra gli elementi dell'array;
'in questo modo quello con indice=Index viene sovrascritto.
CopyMemory ByVal VarPtr(arValues(Index)), ByVal VarPtr(arValues(Index + 1)), _
 (ItemCount - Index) * ItemLen
'"ripuliamo" l'ultimo elemento
ZeroMemory ByVal VarPtr(arValues(ItemCount - 1)), ItemLen
End Sub
Ciao
--
Luca Dormio
l...@sig-la.com
ldo...@tin.it


[SNAP]

o mi mando in tilt il sistema ?
Devi adattarla leggermente (nel senso che devi fargli shiftare comunque una
dimensione per volta) ma dovrebbe funzionare.
in pratica con qualcosa tipo:
For i=0 to 20
    For j=0 to 20
        For k=0 to 20
            CopyMemory ByVal VarPtr(arValues(Index,i,j,k)), ByVal
VarPtr(arValues(Index + 1,i,j,k)), _
             (ItemCount - Index) * ItemLen
        Next
    Next
Next
fai lo shift di tutti i valori contenuti nella prima dimensione.


 End Sub
Io in VB4 non posso usare VarPtr e faccio cosi':
  DefInt I
  DefLng L
  Option Explicit
  Private Declare Sub MoveMemory _
    Lib "kernel32.dll" _
    Alias "RtlMoveMemory" ( _
      Destination As Any _
    , Source As Any _
    , ByVal Length _
    )
Public Sub Main( _
)
Dim l()
  ReDim l(3 To 5)
  Let l(3) = 10
  Let l(4) = 20
  Let l(5) = 30
  Call ShiftArray(l, 3)
  ReDim Preserve l( _
    LBound(l) To UBound(l) - 1)
  Call MsgBox( _
    "3=" & l(3) & "; 4=" & l(4) & ".")
End Sub
Private Sub ShiftArray( _
  ByRef lngArray() _
, ByVal Index _
)
  Call MoveMemory( _
      lngArray(Index) _
    , lngArray(Index + 1) _
    , (UBound(lngArray) - Index) _
    * Len(lngArray(Index)))
End Sub
E' la stessa RtlMoveMemory del tuo CopyMemory ma preferisco chiamarla
MoveMemory perche' dopo l'esecuzione le locazioni Source vengono azzerate.
Quindi non credo serva usare ZeroMemory.
--
Ciao.
Maurizio

 Io in VB4 non posso usare VarPtr [...]
Ho scoperto che non e' vero:
http://www.vb2themax.com/Item.asp?PageID=TipBank&ID=54
--
Ciao.
Maurizio
P.S.: Eeeh... Se ne devono mangiare di panini prima di diventare un Balena!

 Quindi non credo serva usare ZeroMemory.
L'azzeramento dovrebbe avvenire solo nel caso di due array. Qualcuno me lo
conferma, prima che io lo provi?
--
Ciao.
Maurizio