Newsgroup: it.comp.lang.visual-basic
Titolo: Problema incredibile con database Jet

VB6-SP6 WINXP-SP2 MDAC-2.8
Mi capita un problema incredibile: vi spiego sinteticamente.
Dal mio programma VB aggiorno un database di statistica tramite ADO: 
cancello i dati del mese e li ricreo leggendo i documenti di vendita. 
Quando visualizzo i dati ottengo valori SBAGLIATI.
Se compatto il database ottengo i dati GIUSTI.
Vi e' mai capitato?
Evidenzio il fatto che dopo il compattamento i dati sono giusti, quindi 
il programma e' corretto; inoltre se faccio le stesse cose con MSDE al 
posto di Jet i dati sono SEMPRE GIUSTI.
Qualcuno puo' aiutarmi a capire cosa succede? E' cosi' inaffidabile Jet?
Grazie
Gianluca
-----------------------------------------
Messaggio inviato con Excite Newsgroup.
http://www.excite.it/newsgroup

 Jet? Grazie
Innanzitutto non specifichi che dbms utilizzi, e che Jet utilizzi.
Comunque, ci sono diverse possibilità:
- L'errore non sta nei dati, ma nella tua visualizzazione. Chiudendo la 
connessione per riaprirla in esclusiva, e quindi compattare, dopo devi 
riaprirla e quesot può forzare una riapertura dei dati, che magari stavi 
vedendo 'vecchi'.
- Hai impostato di vedere anche i Deleted, per cui finchè non esegui un 
pack, vedi sia i record della vecchia tabella, sia i record inseriti dopo il 
delete.
Ciao
Alberto
-- 
"C'è un Calvelli dentro ognuno di noi" (cit.) 

 Gianluca
Non credo che Jet sia così inaffidabile come tu dici (altrimenti avremmo
già visto molti cadaveri passare per il fiume).
L'unica conclusione ovvia è che sia un problema della tua installazione /
configurazione e/o un problema di access.
Hai provato se un altro database creato "pulito" ha gli stessi problemi?.
Hai provato a chiudere e rigenerare la connessione fra la cancellazione e
l'inserimento?
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it

Intanto grazie per l'aiuto
Uso un db creato con access2003 e Jet 4.0 (inoltre e' installato MDAC 2.8)
Oggi ho provato e riprovato piu' volte gli stessi passaggi (aggiornamento e
visualizzazione) anche con chiusura e riapertura della connessione e i dati che
vedo sono sempre giusti (sigh).
L'errore lo da' dal cliente e lo da' (dava?) anche nel mio computer.
Com'e' questa impostazione dei DELETED? dove la vedo?
grazie
ciao


 della connessione e i dati che vedo sono sempre giusti (sigh).
Sarei curioso di vedere la query con cui estrai/aggiorni i dati.
Magari c'č qualcosa lě dentro.
Se la posti mi fai un piacere.
Ciao
Alberto
-- 
"C'č un Calvelli dentro ognuno di noi" (cit.) 

 Se la posti mi fai un piacere.
per questo ci vuole tempo, perche' ce ne sono due e devo darti anche la
struttura delle tabelle (posso spedire un .zip?)
lo faro' appena possibile
grazie!


 lo faro' appena possibile
Basta la/le query.
E' un copiaincolla (mettendo un breakpoint e stampando la querystring in 
finestra immediata, non con il codice VB tutto concatenato, please...).


finestra immediata, non con il codice VB tutto concatenato, please...).
ecco qua, scusa per il ritardo
-------------------------- inizio codice ------------------------
''' posto questo frammento di modulo (non so quanto sia comprensibile,
ma ci sono troppi moduli e oggetti,
''' che non posso certo postare tutti qui: comunque i nomi delle
funzioni mancanti sono autoesplicativi)
'''
''' nota: non ho trasformato con copia-incolla la stringa sql perche'
non penso sia li' il problema, bensi' penso
''' abbia a che vedere con l'uso dei due recordset contemporanei per
update e addnew presenti nella funzione SetPrecalcArticolo
'''
''' in sintesi questo pezzo di programma serve a popolare una tabella
di statistica giacenze/acquisti/vendite articoli,
''' precalcolando i progressivi per mese, in modo da poter poi
consultare i dati con grande velocita'
Private Function InserisciDati( _
    ByVal vIdDitta As Long, ByVal vCodMag As String, _
    ByVal vAnno As Integer, ByVal vMeseInf As Integer, ByVal vMeseSup
As Integer, _
    ByRef rRecordCount As Long, ByRef rErrDes As String) As Boolean
' ------ previa cancellazione di tutto il periodo
wSQL = CreaSQL(vIdDitta, vCodMag, vAnno, vMeseInf, vMeseSup, rErrDes)
InserisciDati = AdoExecute(wSQL, rRecordCount, rErrDes)
End Function
' inserisco i record in tabella
Private Function CreaSQL( _
    ByVal vIdDitta As Long, ByVal vCodMag As String, _
    ByVal vAnno As Integer, ByVal vMeseInf As Integer, ByVal vMeseSup
As Integer, ByRef rErrDes As String) As String
Dim lGiornoInf     As Date
Dim lGiornoSup     As Date
' per la selezione dei dati uso le date anziche' i mesi
lGiornoInf = PrimoDelMese(vAnno, vMeseInf)
lGiornoSup = UltimoDelMeseAttuale(vAnno, vMeseSup)
CreaSQL = "INSERT INTO " & kTABELLA & _
    " (id_ditta, annomese, anno, mese, id_art, qtagiacini, valgiacini,
qtaacquisti, valacquisti, qtavendite, valvendite, " & _
    " qtaaltrimov, qtagiacfin, valgiacfin, costovenduto)" & _
    " SELECT " & vIdDitta & ",
YEAR(datacompmag)*100+MONTH(datacompmag), YEAR(datacompmag),
MONTH(datacompmag)," & _
    " Docdet.id_art, 0, 0," & _
    " SUM(docdet.qta*segno1*segnomov*IIF(tipomov=" & entpmACQUISTI &
",1,0))," & _
    " SUM(docdet.imponnetto*segno1*segnomov*IIF(tipomov=" &
entpmACQUISTI & ",1,0))," & _
    " SUM(docdet.qta*segno1*segnomov*IIF(tipomov=" & entpmVENDITE &
",1,0))," & _
    " SUM(docdet.imponnetto*segno1*segnomov*IIF(tipomov=" &
entpmVENDITE & ",1,0))," & _
    " SUM(docdet.qta*segno1*segnomov*IIF(tipomov=" & entpmALTRIMOV &
",1,0))," & _
    " 0, 0, 0" & _
    " FROM (((Docdet INNER JOIN Doctes ON Docdet.num_doctes =
Doctes.numero)" & _
    " INNER JOIN TabCaudoc ON Docdet.cod_causale = TabCaudoc.codice)"
& _
    " INNER JOIN TabCaumag1 ON TabCaudoc.id_caumag1 = TabCaumag1.id)"
& _
    " WHERE doctes.id_ditta = " & vIdDitta & " AND Doctes.cod_mag1 = "
& Quote(vCodMag) & _
    " AND Doctes.GestMag = TRUE AND tabcaudoc.gestmag = TRUE AND
tabcaudoc.aggqta1 = TRUE" & _
    " AND datacompmag BETWEEN " & SQLDate(lGiornoInf) & " AND " &
SQLDate(lGiornoSup) & _
    " GROUP BY YEAR(datacompmag), MONTH(datacompmag), Docdet.id_art"
End Function
' aggiorno i valori precalcolati, che adesso sono vuoti (eventualmente
creando i mesi vuoti)
Private Function AggPrecalcolati( _
    ByVal vIdDitta As Long, ByVal vAnno As Integer, ByVal vMeseInf As
Integer, ByVal vMeseSup As Integer, _
    ByRef rRecordCount As Long, ByRef rErrDes As String) As Boolean
' la giacenza iniziale di un mese corrisponde alla giacenza finale del
mese precedente, che potrebbe anche non esistere
' i mesi che non esistono LI CREO, anche se cosi' facendo espando la
tabella, in quanto mi semplificano molto
' la generazione del livello superiore (cat, reparto, ecc) e la
visualizzazione a partire da quest'ultimo
' degli articoli che lo hanno generato
' devo elaborare tutti gli articoli del periodo appena aggiornato e
quelli del mese precedente, che potrebbero non essere
' stati movimentati quest'ultimo periodo appena aggiornato ma
potrebbero essere ancora in giacenza
Dim lRs             As New ADODB.Recordset
Dim lIdArt          As Long
Dim lNewMeseInf     As Integer
' deve partire da true per il ciclo e per l'exit qui sotto
AggPrecalcolati = True
' sposto il mese inferiore indietro di un mese
lNewMeseInf = Max(1, vMeseInf - 1)
' seleziono tutti gli articoli del periodo appena aggiornato e
dell'ultimo mese del periodo precedente,
' che DEVE essere aggiornato
wSQL = "SELECT DISTINCT id_art FROM " & kTABELLA & _
    " WHERE id_ditta = " & vIdDitta & _
    " AND annomese BETWEEN " & GetAnnoMese(vAnno, lNewMeseInf) & " AND
" & GetAnnoMese(vAnno, vMeseSup) & _
    " ORDER BY id_art"
wBool = AdoOpen(lRs, wSQL, enopFORWARDREADONLY, adCmdText)
If Not wBool Then Exit Function ' se non trovo niente non e' detto che
sia un errore
' eseguo su ogni articolo del periodo appena aggiornato: rielaboro
tutto l'anno in quanto potrebbero essere cambiati i valori
With lRs
    If mFeedBack Then AuditInit .RecordCount
    .MoveFirst
    ' ciclo
    While Not .EOF And AggPrecalcolati
        ' sono posizionato su un articolo
        lIdArt = !id_art
        ' parto sempre da gennaio
        AggPrecalcolati = AggPrecalcArticolo(vIdDitta, lIdArt, vAnno,
1, vMeseSup, rErrDes)
        ' audit
        If mFeedBack Then AuditUpdate lIdArt
        ' prossimo articolo
        .MoveNext
    Wend
    .Close
End With
End Function
' eseguo l'elaborazione completa su un articolo
Private Function AggPrecalcArticolo( _
    vIdDitta As Long, vIdArt As Long, vAnno As Integer, vMeseInf As
Integer, vMeseSup As Integer, rErrDes As String) As Boolean
Dim lQtaGiacini As Double
Dim lValGiacini As Double
Dim lCostoMedio As Double
' prendo i valori che mi servono da sta1artanno
mAdoSta1ArtAnno.GetValori vIdDitta, vAnno, vIdArt, lQtaGiacini,
lValGiacini, lCostoMedio, rErrDes
' setto tutti i mesi
AggPrecalcArticolo = SetPrecalcArticolo(vIdDitta, vIdArt, vAnno,
vMeseInf, vMeseSup, lQtaGiacini, lValGiacini, lCostoMedio, rErrDes)
End Function
' per ogni articolo devono esistere tutti i mesi in cui ci sono suoi
valori (di movimentazione o anche solo di giacenza)
Private Function SetPrecalcArticolo( _
    vIdDitta As Long, vIdArt As Long, vAnno As Integer, vMeseInf As
Integer, vMeseSup As Integer, _
    vAnnoQtaGiacIni As Double, vAnnoValGiacIni As Double,
vAnnoCostoMedio As Double, _
    ByRef rErrDes As String) As Boolean
Dim lAdoRsUpdate      As New ADODB.Recordset
Dim lAdoRsAddNew      As New ADODB.Recordset
Dim lLastMese         As Integer
Dim lLastQtaGiacFin   As Double
Dim lLastValGiacFin   As Double
' prendo il primo mese in cui questo articolo esiste ed aggiorno di
conseguenza fino al mesesup
' eseguo ogni volta da inizio anno perche' potrebbe essere variato il
costo medio annuale e per prendere il valore
' giacenza finale del mese precedente al periodo aggiornato
wSQL = "SELECT * FROM " & kTABELLA & _
    " WHERE id_ditta = " & vIdDitta & _
    " AND annomese BETWEEN " & GetAnnoMese(vAnno, 1) & " AND " &
GetAnnoMese(vAnno, vMeseSup) & _
    " AND id_art = " & vIdArt & _
    " ORDER BY annomese"
' apro il recordset per l'update e quello per l'addnew
SetPrecalcArticolo = AdoOpen(lAdoRsUpdate, wSQL, enopUPDATEBATCH,
adCmdText)
SetPrecalcArticolo = AdoOpen(lAdoRsAddNew, wSQL, enopUPDATEBATCH,
adCmdText)
If Not SetPrecalcArticolo Then Exit Function
' init
lLastMese = 0
lLastQtaGiacFin = 0
lLastValGiacFin = 0
Dim lMese As Integer
' eseguo il ciclo fino a che arrivo al mesesup
With lAdoRsUpdate
    While Not .EOF
        lMese = GetMese(!AnnoMese)
        ' record in update
        If lMese = 1 Then
            ' unica eccezione: gennaio 2002 (inizio dei tempi) per il
quale la giac.iniziale la salvo come acquisto
            If vAnno = kannoINIZIOTEMPIMAG Then
                !qtaacquisti = vAnnoQtaGiacIni
                !valacquisti = vAnnoValGiacIni
            Else
                !QtaGiacIni = vAnnoQtaGiacIni
                !ValGiacIni = vAnnoValGiacIni
            End If
        Else
            !QtaGiacIni = lLastQtaGiacFin
            !ValGiacIni = lLastValGiacFin
        End If
        ' converto i valori a NULL in ZERO
        If IsNull(!qtaacquisti) Then !qtaacquisti = 0
        If IsNull(!valacquisti) Then !valacquisti = 0
        If IsNull(!qtavendite) Then !qtavendite = 0
        If IsNull(!valvendite) Then !valvendite = 0
        If IsNull(!qtaaltrimov) Then !qtaaltrimov = 0
        ' valori calcolati
        !QtaGiacFin = !QtaGiacIni + !qtaacquisti - !qtavendite +
!qtaaltrimov
        !ValGiacFin = !QtaGiacFin * vAnnoCostoMedio
        !CostoVenduto = !qtavendite * vAnnoCostoMedio
        ' vedo se tra il mese appena aggiornato ed il precedente ci
sono dei buchi; in questo caso li riempio
        ' con i valori di g.i. e g.f.
        If lLastMese <> 0 And lMese <> lLastMese + 1 Then
            AddMesi lAdoRsAddNew, vIdDitta, vIdArt, vAnno, lLastMese +
1, lMese - 1, lLastQtaGiacFin, lLastValGiacFin
        End If
        ' last
        lLastMese = lMese
        lLastQtaGiacFin = SetDouble(!QtaGiacFin)
        lLastValGiacFin = SetDouble(!ValGiacFin)
        ' prossimo mese
        .MoveNext
    Wend
    ' riempio i mesi dall'ultimo movimentato all'ultimo del periodo
    If lLastMese < vMeseSup Then
        AddMesi lAdoRsAddNew, vIdDitta, vIdArt, vAnno, lLastMese + 1,
vMeseSup, lLastQtaGiacFin, lLastValGiacFin
    End If
    ' aggiorno fisicamente i record e chiudo
    .UpdateBatch
    .Close
End With
' aggiungo fisicamente i record e chiudo
With lAdoRsAddNew
    .UpdateBatch
    .Close
End With
' verificare se ci sono problemi per la mancanza dei mesi fino a
dicembre
End Function
Private Sub AddMesi( _
    rAdoRsAddNew As ADODB.Recordset, vIdDitta As Long, vIdArt As Long,
_
    vAnno As Integer, vMeseInf As Integer, vMeseSup As Integer,
vQtaGiacFin As Double, vValGiacFin As Double)
Dim lNewMese As Integer
' scrivo solo se ci sono valori da scrivere
If vQtaGiacFin <> 0 Then
    For lNewMese = vMeseInf To vMeseSup
        With rAdoRsAddNew
            ' nuovo mese -----------------------------------------
            .AddNew
            !id_ditta = vIdDitta
            !AnnoMese = GetAnnoMese(vAnno, lNewMese)
            !anno = vAnno
            !mese = lNewMese
            !id_art = vIdArt
            !QtaGiacIni = vQtaGiacFin
            !ValGiacIni = vValGiacFin
            !qtaacquisti = 0
            !valacquisti = 0
            !qtavendite = 0
            !valvendite = 0
            !qtaaltrimov = 0
            !QtaGiacFin = vQtaGiacFin
            !ValGiacFin = vValGiacFin
            !CostoVenduto = 0
            ' nuovo mese -----------------------------------------
        End With
    Next
End If
End Sub

 ecco qua
Mi sembrava di avere chiesto una determinata cosa.
Evidentemente non hai bisogno d'aiuto.
Ciao
Alberto
-- 
"C'è un Calvelli dentro ognuno di noi" (cit.) 

Evidentemente non hai bisogno d'aiuto.
Ti chiedo scusa. Ho postato il pezzo di programma perche'
l'aggiornamento completo avviene solo tramite codice, ed ho pensato di
fare meglio postando tutto.
La query del primo aggiornamento e':
INSERT INTO sqlStatArtMese (anno, mese, annomese, id_art, qtagiacini,
valgiacini, qtaacquisti, valacquisti, qtavendite, valvendite,
qtaaltrimov, qtagiacfin, valgiacfin)  SELECT YEAR(datacompmag),
MONTH(datacompmag), YEAR(datacompmag)*100+MONTH(datacompmag),
Docdet.id_art, 0, 0, SUM(docdet.qta*segnomov*IIF(tipomov=1,1,0)),
SUM(docdet.imponnetto*segnomov*IIF(tipomov=1,1,0)),
SUM(docdet.qta*segnomov*IIF(tipomov=2,1,0)),
SUM(docdet.imponnetto*segnomov*IIF(tipomov=2,1,0)),
SUM(docdet.qta*segnomov*IIF(tipomov=4,1,0)), 0, 0 FROM (((Docdet INNER
JOIN Doctes ON Docdet.num_doctes = Doctes.numero) INNER JOIN TabCaudoc
ON Docdet.cod_causale = TabCaudoc.codice) INNER JOIN TabCaumag1 ON
TabCaudoc.id_caumag1 = TabCaumag1.id) WHERE Doctes.cod_mag1 = "01" AND
Doctes.GestMag = TRUE AND tabcaudoc.gestmag = TRUE AND
tabcaudoc.aggqta1 = TRUE  AND datacompmag BETWEEN  #01/01/2005#  AND
#04/30/2005#  GROUP BY YEAR(datacompmag), MONTH(datacompmag),
Docdet.id_art
Poi eseguo la funzione SetPrecalcArticolo per ogni articolo: questa
funzione imposta i campi di giacenza finale che, non l'avevo
precisato, sono quelli che (prima del compattamento) risultano per
certi articoli sbagliati.
Questa pero' avviene tramite codice VB.
Ciao e grazie per l'attenzione
Gianluca