Order genereren vanuit een offerte

Status
Niet open voor verdere reacties.
Eens temeer blijkt hoe simpel je dat met DAO (nogmaals: geen extra bibliotheken nodig) kunt oplossen.
Code:
    strSQL = "SELECT OfferteID, Item, Qty, Unitprice, Discount, Total, Artikeltekst, ArtikelID, [Description /partnumber], Artikelnummer FROM [Offerte-inhoud] " _
    & "WHERE OfferteID=" & Me.OfferID
    Set rst = CurrentDb.OpenRecordset(strSQL)
    Set rso = CurrentDb.OpenRecordset("Order-inhoud")
    If Not rst.RecordCount = 0 Then
        Do While Not rst.EOF
            With rso
                .AddNew
                !OrderID = iOrderID
                !Item = rst!Item
                !Qty = rst!Qty
                !Unitprice = rst!Unitprice
                !Discount = rst!Discount
                !Offertenummer = rst!OfferteID
                !Artikeltekst = rst!Artikeltekst
                !ArtikelID = rst!ArtikelID
                !Artikelnummer = rst!Artikelnummer
                tmp = rst.Fields(9).Name
                tmp = rst.Fields(8).Name
                .Fields(4) = rst.Fields(8)
                !OrderID = iOrderID
                .Update
            End With
            rst.MoveNext
        Loop
        rst.Close
    End If
 
Ik ben erg blij met de werking van het kopiëren van gegevens naar een andere tabel.
Lastige is dat ik dit nu ook voor inkooporders moet doen (daarna ook nog wat voor pakbonnen, facturen etc), maar zonder kennis van het programmeren loop ik toch tegen een probleem aan.

Ik heb getracht de code te herschrijven voor "order omzetten naar inkooporder", maar krijg nu de foutmelding "error 64000 - no active order found with orderID 42 ...etc.

Waar zou het probleem kunnen zitten?

Ik heb de database opnieuw geupload.
 

Bijlagen

  • CRM_Ontwikkel 13-8-2020.zip
    413,5 KB · Weergaven: 17
De fout zit in de functie fCopyInkooporderHeader. Daar probeer je het niet-bestaande veld Inkooporders!KlantID in te vullen. Aangezien dat veld niet bestaat in de tabel gaat de functie naar de error-handling en geeft als resultaat -1.
Dit zorgt ervoor dat in de hoofd procedure sCopyOrderToInkooporder de lijn:
Code:
If lngInkooporderHeader = -1 Then Err.Raise 64000, , "No active Order found with orderID = " & lngOrderID
een error genereert, die je de foutmelding 64000 geeft.

Om dat te zien kan je door de code steppen: je zet een waypoint (rode bol) in de code door in de linkermarge voor de regel te klikken waar je wil stoppen.
Waypoint.JPG
Als je de code dan uitvoert dan stopt hij daar en kan je die verder regel per regel uitvoeren met F8 of via de knop Step Into in de Debug werkbalk (op het scherm te zetten door in de VBA omgeving met de rechtermuisknop in de werkbalk te klikken en in de snelmenu de werkbalk aan te klikken). Je ziet dan op welke regel de code in de fout gaat.
Je kan de waypunt verwijderen door opnieuw op de rode bol te klikken of via de menu-optie Debug -> clear all breakpoints
 
Bedankt voor je reactie.
Overigens weet ik niet hoe ik de code kan uitvoeren, want als ik op het groene "afspeel"pijltje klik opent een scherm en vraagt die om een macro?
 
Dit zou betekenen dat ik de leverancier van de artikelen zou moeten ophalen uit de artikelkaart, anders weet het systeem niet welke Leverancier_ID de inkooporder moet gebruiken.

Kun je me helpen hoe dat is te realiseren?
Mocht het heel ingewikkeld zijn dan is het misschien een optie om een standaard leverancier te gebruiken (degene die het meest wordt gebruikt) en dit na het creëren van de inkooporder handmatig aan te passen.
Maar uiteraard kies ik liever voor de geautomatiseerde oplossing om fouten te voorkomen.
 
De code moet je aan een event procedure van je formulier hangen, check even in de design weergave van de knop die ik toegevoegd heb en kijk naar de event property OnClick. Als je daar op de knop met drie puntjes klikt kom je in de bijbehorende code terecht. Je start de code door op de knop in het formulier te klikken, of als je wil testen in het immediate pane de procedure op te roepen met een call instructie:
callinstructie.JPG

om de leverancier erbij te halen moet je de recordset via een sql instructie opbouwen, ik kijk er later wel eens naar
 
In feite moet je dus een inkooporder aanmaken per leverancier. Als je een verkoopsorder hebt met 3 artikelen van 2 verschillende leveranciers moet je daarvoor dus 2 inkooporders aanmaken. Probeer eens met code als (zelf aanpassen waar nodig):

Code:
Public Sub sCopyOrderToInkooporder(lngOrderID As Long)
On Error GoTo Err_sCopyOrderToInkooporder:

    Dim lngInkooporderHeader As Long
    Dim rstLeveranciers As New ADODB.Recordset
    Dim cmdAddInkooporderDetails As New ADODB.Command
    Dim lngCountDetails As Long, lngAlldetails As Long, intCountOrders As Integer
    Dim strSQL As String
    
    strSQL = "SELECT  artikelen.LeverancierID FROM artikelen INNER JOIN [Order-inhoud] ON artikelen.ArtikelID = [Order-inhoud].ArtikelID " & _
                    " where orderID = " & lngOrderID & " GROUP BY [Order-inhoud].OrderID, artikelen.LeverancierID;"
    rstLeveranciers.Open strSQL, CurrentProject.Connection, adOpenForwardOnly, adLockReadOnly
    With rstLeveranciers
        If Not (.BOF And .EOF) Then
            .MoveFirst
            Do While .EOF = False
                lngInkooporderHeader = fCopyInkooporderHeader(lngOrderID, !LeverancierId)
                If lngInkooporderHeader = -1 Then Err.Raise 64000, , "No active Order found with orderID = " & lngOrderID
                intCountOrders = intCountOrders + 1
               
                cmdAddInkooporderDetails.ActiveConnection = CurrentProject.Connection
                cmdAddInkooporderDetails.CommandType = adCmdText
                cmdAddInkooporderDetails.CommandText = "INSERT INTO [Inkooporder-inhoud] ( InkooporderID,  Item, Qty, Unitprice, Discount, Total, Offertenummer, Artikeltekst, ArtikelID, Artikelnummer, Partnumber ) " & _
                        " select " & lngInkooporderHeader & " , Item, Qty, Unitprice, Discount, Total, Offertenummer, Artikeltekst, [Order-inhoud].ArtikelID," & _
                        " [Order-inhoud].Artikelnummer, [Order-inhoud].Partnumber " & _
                        " from  [Order-inhoud]  INNER JOIN artikelen ON [Order-inhoud].ArtikelID = Artikelen.ArtikelID " & _
                        " where OrderID = " & lngOrderID & " and LeverancierID = " & !LeverancierId
                Debug.Print cmdAddInkooporderDetails.CommandText
                cmdAddInkooporderDetails.Execute lngCountDetails
                lngAlldetails = lngAlldetails + lngCountDetails
                .MoveNext
            Loop
        End If
        .Close
    End With
   
    
    MsgBox intCountOrders & "Order(s) created with " & lngAlldetails & " order lines"
        
Exit_sCopyOrderToInkooporder:
    Set cmdAddInkooporderDetails = Nothing
    Set rstLeveranciers = Nothing
    Exit Sub
    
Err_sCopyOrderToInkooporder:
    MsgBox "Error " & Err.Number & " - " & Err.Description & " in method Copy order to Inkooporder " & vbLf & "Please contact your application administrator."
    Resume Exit_sCopyOrderToInkooporder

End Sub
Private Function fCopyInkooporderHeader(lngOrder, lngLeverancier) As Long
On Error GoTo Err_fCopyInkooporderHeader

    Dim rstOrder As New ADODB.Recordset
    Dim rstInkooporder As New ADODB.Recordset
    Dim lngInkooporderID As Long
   
    rstOrder.Open "select * from Orders where OrderID = " & lngOrder, CurrentProject.Connection, adOpenKeyset, adLockPessimistic
    With rstOrder
        If .BOF And .EOF Then Err.Raise 64000
        rstInkooporder.Open "select * from Inkooporders where 1=0", CurrentProject.Connection, adOpenKeyset, adLockPessimistic
        .MoveFirst
        rstInkooporder.AddNew
        rstInkooporder!OrderDatum = Date
        rstInkooporder!Status = "Lopend"
        rstInkooporder!Leverancier_ID = lngLeverancier
        rstInkooporder.Update
        lngInkooporderID = rstInkooporder!InkooporderID
        rstInkooporder.Close
        .Close
    End With
    fCopyInkooporderHeader = lngInkooporderID
        

Exit_fCopyinkooporderHeader:
    Set rstOrder = Nothing
    Set rstOrder = Nothing
    Exit Function
    
Err_fCopyInkooporderHeader:
Debug.Print Err.Number & Err.Description
    fCopyInkooporderHeader = -1
    Resume Exit_fCopyinkooporderHeader
    
End Function
 
Bedankt!

Wederom een fantastische oplossing.
Ik zie alleen dat het veld verkooporder (dus het OrderID van verkooporders) niet wordt meegenomen naar de Inkooporder header (verkooporder).
Dit is een belangrijk veld omdat ik dan eenvoudig kan zien bij welke verkooporder de betreffende inkooporder hoort.

Kun je misschien aangeven waar ik dit veld in de code moet toevoegen?

bedankt.
 
In de private functie:
Private Function fCopyInkooporderHeader(lngOrder, lngLeverancier) As Long

daar kan je tussen de andere (orderdatum, status, ...) opvullijnen de volgende lijn toevoegen:

rstInkooporder!VerkoopOrderID = lngOrder
 
Top bedankt.

Ik snap de logica nog steeds niet helemaal :confused: maar het werkt perfect ;-).
Toch hoop ik dat ik het ga begrijpen, aangezien ik deze code voor andere zaken ook nodig ga hebben (pakbon, factuur etc).
 
Status
Niet open voor verdere reacties.
Terug
Bovenaan Onderaan