Data van de ene tabel naar de andere kopiëren

  • Onderwerp starter Onderwerp starter Gum2
  • Startdatum Startdatum
Status
Niet open voor verdere reacties.

Gum2

Gebruiker
Lid geworden
30 mrt 2007
Berichten
80
Ik heb een tabel met machine data waarvan ik mbv VBA bepaalde records naar een TEMP tabel wil kopiëren.
Vanuit de tabel 'Tbl_Errorskip' wil ik bepaalde records uitsluiten die niet gekopieerd mogen worden.
Hiervoor gebruik ik de volgende code:

Code:
Sub test2()
Set EQ = CurrentDb.OpenRecordset("Tbl_Equipment")
        
        EQ.MoveLast
        EQ.MoveFirst
        
        Do While Not EQ.EOF
        
            machine = EQ!Equipment
                     
            E1 = "ERROR: 0501"
            E2 = "ERROR: 0011"
            E3 = "ERROR: 0012"

               
            DoCmd.RunSQL "INSERT INTO TEMP ( Batch, Datum, Error, CountOfError, Omschrijving, Fatal, Equipment )" _
            & "SELECT [Batch], [Datum], [Error], Count(Error) AS CountOfError, [Omschrijving], [Fatal], [Equipment]" _
            & "FROM LM" & machine & " GROUP BY  [Datum],[Batch], [Error], [Error], [Omschrijving], [Fatal], [Equipment]" _
            & "HAVING Datum Between [forms]![Frm_Select]![StartDate] And [forms]![Frm_Select]![EndDate2]AND Error <> """ & E1 & """" _
            & "AND Datum Between [forms]![Frm_Select]![StartDate] And [forms]![Frm_Select]![EndDate2]AND Error <> """ & E2 & """" _
            & "AND Datum Between [forms]![Frm_Select]![StartDate] And [forms]![Frm_Select]![EndDate2]AND Error <> """ & E3 & """" _
            & "AND Datum Between [forms]![Frm_Select]![StartDate] And [forms]![Frm_Select]![EndDate2]AND Error <> """ & E4 & """;"
            
            EQ.MoveNext
            
        Loop
        
        EQ.Close

End Sub

Bovenstaande code werkt op zich goed.
Indien ik de errocodes nu in een tabel 'Tbl_Errorskip' onderbreng dan heb ik een probleem om de errorcodes uit te lezen met onderstaande code. Het op deze manier creëren van een E1 t/m E4 variabelen wil niet lukken. Wat doe ik fout?

Code:
Sub test()
Set EQ = CurrentDb.OpenRecordset("Tbl_Equipment")
        
        EQ.MoveLast
        EQ.MoveFirst
        
        Do While Not EQ.EOF
        
            machine = EQ!Equipment
                     
            t = 1
            
            Set EC = CurrentDb.OpenRecordset("Tbl_Errorskip")
              
            While Not EC.EOF
                
                E& t = EC!ErrorsSkipped
                EC.MoveNext
                t = t + 1
                
            Wend
               
            DoCmd.RunSQL "INSERT INTO TEMP ( Batch, Datum, Error, CountOfError, Omschrijving, Fatal, Equipment )" _
            & "SELECT [Batch], [Datum], [Error], Count(Error) AS CountOfError, [Omschrijving], [Fatal], [Equipment]" _
            & "FROM LM" & machine & " GROUP BY  [Datum],[Batch], [Error], [Error], [Omschrijving], [Fatal], [Equipment]" _
            & "HAVING Datum Between [forms]![Frm_Select]![StartDate] And [forms]![Frm_Select]![EndDate2]AND Error <> """ & E1 & """" _
            & "AND Datum Between [forms]![Frm_Select]![StartDate] And [forms]![Frm_Select]![EndDate2]AND Error <> """ & E2 & """" _
            & "AND Datum Between [forms]![Frm_Select]![StartDate] And [forms]![Frm_Select]![EndDate2]AND Error <> """ & E3 & """" _
            & "AND Datum Between [forms]![Frm_Select]![StartDate] And [forms]![Frm_Select]![EndDate2]AND Error <> """ & E4 & """;"
            
            EQ.MoveNext
            
        Loop
        
        EQ.Close

End Sub
 
Je fout zit in ieder geval hier: E& t = EC!ErrorsSkipped. Om te beginnen zou er al een spatie moeten tussen E en &, maar dat lost het probleem helaas niet op voor je. Je kunt op deze manier namelijk geen variabelen maken. Die moet je van tevoren declareren, en dan kun je er waarden aan toewijzen. Wat je wel kunt gebruiken, is een Array variabele.
Een ander probleem, al is dat op zich niet iets dat de procedure tegen houdt, is dat je de variabelen bij elk record opnieuw vult met dezelfde waarden. Dat is niet erg efficiënt; je kunt ze beter in één keer vullen lijkt mij, en dan pas de toevoegquery uitvoeren. Dat scheelt toch wat tijd. E.e.a. zou ik dan ook ongeveer zo oplossen:

Code:
Sub Test()
Dim eT() As String
Dim Machine As String
Dim i As Integer
Dim strSQL As String

    With CurrentDb.OpenRecordset("Tbl_Errorskip")
        ReDim eT(.RecordCount - 1)
        .MoveFirst
        Do While Not .EOF
            eT(i) = .Fields("ErrorsSkipped").Value
            i = i + 1
            .MoveNext
        Loop
        .Close
    End With

    With CurrentDb.OpenRecordset("Tbl_Equipment")
        .MoveFirst
        Do While Not .EOF
            Machine = .Fields("Equipment").Value
            strSQL = "INSERT INTO TEMP ( Batch, Datum, Error, CountOfError, Omschrijving, Fatal, Equipment )" _
                & "SELECT [Batch], [Datum], [Error], Count(Error) AS CountOfError, [Omschrijving], [Fatal], [Equipment]" _
                & "FROM LM" & Machine & " GROUP BY  [Datum],[Batch], [Error], [Error], [Omschrijving], [Fatal], [Equipment] "
            For i = LBound(eT) To UBound(eT)
                If i = LBound(eT) Then
                    strSQL = strSQL & "HAVING "
                Else
                    strSQL = strSQL & "AND "
                End If
                strSQL = strSQL & "Datum Between CDate(" & CDbl(Me.StartDate) & ") And CDate(" & CDbl(Me.EndDate2) & ") " _
                    & "And Error <> '" & eT(i) & "' "
            Next i
            DoCmd.RunSQL (strSQL)
        Loop
        .Close
    End With

End Sub

Deze code werkt op deze manier als je niks hebt veranderd aan je Option Base. Heb je die anders ingesteld, dan moet je de array anders vullen.
 
Ok OctaFish, bedankt voor jouw reactie.
Momenteel heb ik even geen tijd om ermee aan de slag te gaan. Ik zal morgen kijken of ik het met jouw tips werkend kan krijgen!
 
Ik heb de code uiteraard niet getest, omdat ik deze tabellen niet heb. Check hem eventueel door er eerst een losse query van te maken. Ik doe dat meestal zo:

Code:
Dim tmp
tmp=Inputbox("","",strSQL)
Exit Sub

Deze code gebruik je om de volledig opgebouwde code in een inputbox uit te lezen. Die kopieer je, vervolgens maak je een nieuwe query, en daar plak je de gekopieerde sql code in het SQL venster. Vervolgens kijk je wat de query doet. Geeft-ie een foutmelding, dan moet er nog wat gesleuteld worden...
 
Bedankt voor de aanvullende tips Octafish. Ik ga er morgen mee aan de slag!
 
Ik heb inmiddels de code toegepast en loop nu tegen het volgende probleem aan.
Bij het testen vd code krijg ik in onderstaande regel

Code:
strSQL = strSQL & "Datum Between CDate(" & CDbl(Me.StartDate) & ") And CDate(" & CDbl(Me.EndDate2) & ") " _
                    & "And Error <> '" & eT(i) & "' "

de melding dat bij CDbl(Me.StartDate) en CDbl(Me.Enddate2) de typen niet met elkaar overeenkomen.
Ik heb vervolgens geprobeerd beide data van het juiste format te voorzien dmv

Code:
Me.StartDate = Format(Me.StartDate, "dd mmm yyyy")
Me.EndDate = Format(Me.EndDate, "dd mmm yyyy")

maar dit hielp niet. De foutmelding bleef hetzelfde.
Nadat ik CDbl had weggehaald dan liep de code wel door maar dan kreeg ik uiteindelijk weer een probleem bij het uitvoeren van query expressie.
Ik krijg dan het bericht:

Fout 3075 tijdens uitvoering:

Syntaxisfout (operator ontbreekt) in query-expressie Datum Between CDate(01 nov 2011) And CDate(09 nov 2011) And Error <> "ERROR:AA-0001".

Er gaat volgens mij dus iets fout met de datum. Maar wat?
 
Ik heb de code inmiddels als volgt aangepast:

Code:
strSQL = strSQL & "Datum Between #" & (Me.StartDate) & "# And #" & (Me.EndDate2) & "# " _
                        & "And Error <> '" & E(i) & "' "

Nu werkt het prima!
Verder nog .MoveNext toegevoegd tussen DoCmd.RunSQL (strSQL) en Loop aangezien de code in een loop bleef hangen.
Bedankt voor alle hulp !!

De volledige code is nu als volgt :

Code:
Dim E() As String
    Dim Machine As String
    Dim i As Integer
    Dim strSQL As String
    
    
    
        With CurrentDb.OpenRecordset("Tbl_Errorskip")
            ReDim E(.RecordCount - 1)
            .MoveFirst
            Do While Not .EOF
                E(i) = .Fields("ErrorsSkipped").Value
                i = i + 1
                .MoveNext
            Loop
            .Close
        End With
    
        With CurrentDb.OpenRecordset("Tbl_Equipment_All")
            .MoveFirst
            Do While Not .EOF
                Machine = .Fields("Equipment").Value
                strSQL = "INSERT INTO TEMP ( Batch, Datum, Error, CountOfError, Omschrijving, Fatal, Equipment )" _
                    & "SELECT [Batch], [Datum], [Error], Count(Error) AS CountOfError, [Omschrijving], [Fatal], [Equipment]" _
                    & "FROM LM" & Machine & " GROUP BY  [Datum],[Batch], [Error], [Error], [Omschrijving], [Fatal], [Equipment] "
                For i = LBound(E) To UBound(E)
                    If i = LBound(E) Then
                        strSQL = strSQL & "HAVING "
                    Else
                        strSQL = strSQL & "AND "
                    End If
                    strSQL = strSQL & "Datum Between #" & (Me.StartDate) & "# And #" & (Me.EndDate2) & "# " _
                        & "And Error <> '" & E(i) & "' "
                Next i
                'Dim tmp
                'tmp = InputBox("", "", strSQL)
                'Exit Sub
                DoCmd.RunSQL (strSQL)
                .MoveNext
            Loop
            .Close
        End With
 
Je gaat nog tegen problemen aanlopen met je datums, omdat VBA datums interpreteert als Amerikaanse datums, en jij vermoedelijk de Nederlandse datumnotatie gebruikt. Daarbij wordt 9-7-2011 (9 juli) in de query vertaald naar 7 september. Vandaar dat ik in mijn vba queries altijd de datum omzet naar een getal met CDbl(Me.StartDate) en in de query wordt de getalwaarde met CDate weer terug vertaald naar de juiste datum. Het commando CDate(40858) levert dus de datum 11-112011 op.
Als de opdracht bij jou niet goed werkt, dan ligt dat niet aan de query, maar aan je veldinhoud. Ik zou daar dus ook naar kijken: wordt de datum wel omgezet naar een getal? Jouw voorbeeldje (CDate(01 nov 2011)) is een foute opdracht, omdat je een datum in het CDate commando zet, en geen getal. En dan werkt hij uiteraard niet. Probeer dus eens een check op de inhoud van het datumveld; msgbox Cdbl(Me.StartDate) bijvoorbeeld. Daar moet dan een getal uit rollen.

Met een specifieke opmaak code kun je de datum overigens ook wel goed inlezen, maar niet op de manier waarop jij het hebt gedaan; die code doet niks aan de datumverwisseling. Je maakt dan het beste eerst een constante aan (algemeen of in de procedure, dat maakt niet uit)

Code:
Const strcJetDate = "\#mm\/dd\/yyyy\#"  'Do NOT change it to match your local settings.
Format(Me.StartDate, strcJetDate)

Als je deze notatie niet gebruikt, krijg je geheid problemen met je datums...
 
Wederom bedankt voor de tips. Ik ga ermee aan de slag !
 
Ik heb inmiddels gevonden dat de datum notatie in mijn formulier 'Frm_Select' niet juist was.
De fout zat in de code die ik gebruikt had voor het kalenderbesturingselement.
De code :

Code:
Forms!Frm_Select!StartDate.Value = Format(Calendar.Value, "yyyy-mm-dd")

heb ik nu gewijzigd naar:

Code:
Forms!Frm_Select!StartDate = calendar

Indien ik nu gebruik maak van CDate en CDbl krijg ik geen foutmelding meer dat de typen niet overeenkomen. :thumb:

Code ziet er nu als volgt uit:

Code:
Dim E() As String
    Dim Machine As String
    Dim i As Integer
    Dim strSQL As String
    
    
    
        With CurrentDb.OpenRecordset("Tbl_Errorskip")
            ReDim E(.RecordCount - 1)
            .MoveLast
            .MoveFirst
            Do While Not .EOF
                E(i) = .Fields("ErrorsSkipped").Value
                i = i + 1
                .MoveNext
            Loop
            .Close
        End With
    
        With CurrentDb.OpenRecordset("Tbl_Equipment_All")
            .MoveLast
            .MoveFirst
            Do While Not .EOF
                Machine = .Fields("Equipment").Value
                strSQL = "INSERT INTO TEMP ( Batch, Datum, Error, CountOfError, Omschrijving, Fatal, Equipment )" _
                    & "SELECT [Batch], [Datum], [Error], Count(Error) AS CountOfError, [Omschrijving], [Fatal], [Equipment]" _
                    & "FROM LM" & Machine & " GROUP BY  [Datum],[Batch], [Error], [Error], [Omschrijving], [Fatal], [Equipment] "
                For i = LBound(E) To UBound(E)
                    If i = LBound(E) Then
                        strSQL = strSQL & "HAVING "
                    Else
                        strSQL = strSQL & "AND "
                    End If
                                        
                   strSQL = strSQL & "Datum Between CDate(" & CDbl(Me.StartDate) & ") And CDate(" & CDbl(Me.EndDate) & ") " _
                    & "And Error <> '" & E(i) & "'" & "AND Error Like 'ERROR: " & Me.ErrorCode & "*'"
                    
                Next i
                DoCmd.RunSQL (strSQL)
                .MoveNext
            Loop
            .Close
        End With
 
Is het probleem daarmee opgelost? Dan kan de vraag denk ik op opgelost?
 
Status
Niet open voor verdere reacties.
Terug
Bovenaan Onderaan