Subtrahieren von Werten in Abhängigkeit von einer Variablen, die mit 'c von einem Transaktions-Dataset beginntHallo, ich habe ein Datenfeld mit einer Spalte namens 'InvoiceNumber' (Rechnungsnummer, Beispiel 541431 ). Und noch eine Spalte mit dem Namen 'Stockcode'.
Wenn InvoiceNo mit einem C beginnt (Beispiel C541433 ) und es entspricht einem vorherigen StockCode Ich muss die Menge und / oder den Stückpreis aus meiner Analyse streichen . (es bedeutet, dass ein Kunde den Artikel zurückgegeben hat). Ich versuche, eine RFM-Analyse und eine Warenkorbanalyse durchzuführen, aber zuerst muss ich dies berücksichtigen. Wie kann ich die Summe, die pro Kunden-ID ausgegeben wurde, sowohl in der Menge als auch im Einheitspreis abziehen, wenn sie einen Artikel zurückgeben (und ich eine Zeile mit einer Invoiceno habe, die mit 'C' beginnt)
Wie kann ich dieses Problem lösen? Ich habe 500.000 Zeilen mit Transaktionsdaten.
| RechnungsNr | StockCode | Beschreibung | Menge | Rechnungsdatum | Stückpreis | Kundennummer | Land |
| 541431 | 23166 | MITTLERE KERAMISCHE TOP LAGERDOSE | 74215 | 18/1/2011 10:01 | 1,04 | 12346 | Großbritannien |
| C541433 | 23166 | MITTLERE KERAMISCHE TOP LAGERDOSE | -74215 | 18/1/2011 10:17 | 1,04 | 12346 | Großbritannien |
| 537626 | 85116 | SCHWARZER CANDELABRA T-LIGHTHALTER | 12 | 12.07.2010 14:57 | 2.1 | 12347 | Island |
| 537626 | 22375 | AIRLINE BAG VINTAGE JET SET BRAUN | 4 | 12.07.2010 14:57 | 4.25 | 12347 | Island |
| 537626 | 71477 | FARBGLAS. STAR T-LIGHT HALTER | 12 | 12.07.2010 14:57 | 3.25 | 12347 | Island |
| 537626 | 22492 | MINI PAINT SET VINTAGE | 36 | 12.07.2010 14:57 | 0,65 | 12347 | Island |
| 537626 | 22771 | KLARER SCHUBKNOPF ACRYLISCHER EDWARDIAN | 12 | 12.07.2010 14:57 | 1,25 | 12347 | Island |
| 537626 | 22772 | ROSA SCHUBKNOPF ACRYLISCHER EDWARDIAN | 12 | 12.07.2010 14:57 | 1,25 | 12347 | Island |
| 537626 | 22773 | GRÜNER SCHUBKNOPF ACRYLISCHER EDWARDIAN | 12 | 12.07.2010 14:57 | 1,25 | 12347 | Island |
| 537626 | 22774 | ROTER SCHUBLADEKNOPF ACRYLISCHER EDWARDIAN | 12 | 12.07.2010 14:57 | 1,25 | 12347 | Island |
| 537626 | 22775 | PURPLE-SCHUBLADE ACRYLISCHER EDWARDIAN | 12 | 12.07.2010 14:57 | 1,25 | 12347 | Island |
| 537626 | 22805 | BLAUER SCHUBLADEKNOPF ACRYLISCHER EDWARDIAN | 12 | 12.07.2010 14:57 | 1,25 | 12347 | Island |
| 537626 | 22725 | ALARMUHR BAKELIKE SCHOKOLADE | 4 | 12.07.2010 14:57 | 3,75 | 12347 | Island |
| 537626 | 22726 | ALARMUHR BAKELIKE GRÜN | 4 | 12.07.2010 14:57 | 3,75 | 12347 | Island |
| 537626 | 22727 | WECKER BAKELIKE ROT | 4 | 12.07.2010 14:57 | 3,75 | 12347 | Island |
| 537626 | 22728 | Wecker BAKELIKE ROSA | 4 | 12.07.2010 14:57 | 3,75 | 12347 | Island |
| 537626 | 22729 | WECKER BAKELIKE ORANGE | 4 | 12.07.2010 14:57 | 3,75 | 12347 | Island |
Re: Subtrahieren von Werten in Abhängigkeit von einer Variablen, die mit 'c beginnt, von einem TransaktionsdatensatzNachfolgend finden Sie eine neue Version, die die Daten in einem einzigen Durchgang der Datentabelle vollständig abgleichen kann. Die Verarbeitung dauert etwa 30 Sekunden
Names Default To Here( 1 );
dt = Current Data Table();
// Add a RowNum column to permit the reordering back to
// the original order after processing
dt << New Column( "RowNum", formula( Row() ) );
dt:RowNum << delete property( "formula" );
// Sort the data so that processing can start at the
// top of the data, and flow downward, and the required
// data are grouped together and in row order
dt << Sort(
By( :CustomerID, :StockCode, :RowNum ),
Order( Ascending, Ascending, Descending ),
Replace Table( 1 )
);
// Find the starting row, that is, the first row with a
// CustomerID value
Start = 1;
While( Is Missing( dt:CustomerID[Start] ) == 1, Start++ );
// Loop across all rows, starting with the first non missing
// CustomerID
For( RowCNT = Start, RowCNT <= N Rows( dt ), RowCNT++,
// When the CustomerID or StockCode changes, or if this is
// the first loop, zero out the UnBookingAmount
If(
Try( :CustomerID[RowCNT - 1], "" ) != :CustomerID[RowCNT] |
Try( :StockCode[RowCNT - 1], "" ) != :StockCode[RowCNT] | RowCNT == Start,
UnBookingAmount = 0
);
// If this is a Change Invoice, then add the change to
// the running UnBookingAmount (Summing a negative amount actually makes
// the value of UnBookingAmount even more negative)
If( Starts With( :InvoiceNo[RowCNT], "C" ) == 1,
UnBookingAmount = Sum( UnBookingAmount, :Quantity[RowCNT] );
:Quantity[RowCNT] = 0;
, // Else
// Reduct the order by the current value of UnBookingAmount
:Quantity[RowCNT] = Sum( UnBookingAmount, :Quantity[RowCNT] );
// If the Quantity is less than zero, that means more
// UnBooking amount needs to be subtracted on earlier
// orders so reset the UnBookingAmountt remaining to be reconciled,
// and set the current order to 0
If( :Quantity[RowCNT] < 0,
UnBookingAmount = :Quantity[RowCNT];
:Quantity[RowCNT] = 0;
, // Else
// If the Quantity is >= 0 that means all UnBookings
// have been handled, so set the UnBookingAmount to 0
UnBookingAmount = 0
);
);
);
// Reorder the table back to the original order
dt << Sort( By( :RowNum ), Order( Ascending ), Replace Table( 1 ) );
// Delete the no longer needed RowNum column
dt << delete columns( "RowNum" );
Re: Subtrahieren von Werten in Abhängigkeit von einer Variablen, die mit 'c beginnt, von einem TransaktionsdatensatzDanke, Kevin! Ja, ich würde diese 1 "links" in die Buchhaltung aufnehmen
@ Kevin_Anderson schrieb:
Hallo Alexllorens!
Ist das etwas, was du einmal machst, oder etwas, das du wiederholt machst? Ich gehe davon aus, dass die Antwort "wiederholt" ist. Wenn ja, sollten Sie ein JSL-Skript schreiben.
Kann ein Kunde weniger als eine vollständige Bestellung zurücksenden? Mit anderen Worten: Wenn ein Kunde 50 Einheiten bestellt und 49 zurückgegeben hat, möchten Sie den Restbetrag in Ihre Buchhaltung aufnehmen?
Re: Subtrahieren von Werten in Abhängigkeit von einer Variablen, die mit 'c beginnt, von einem TransaktionsdatensatzIch habe nicht alle Nuancen genau verstanden, insbesondere was den zusammengesetzten Primärschlüssel zum Identifizieren von Datensätzen, die angepasst werden müssen, oder welche Anpassungen vorgenommen werden müssen.
Es kann jedoch sein, dass eine Weiterentwicklung des folgenden Codes dies tun könnte. Kein fairer Vergleich, aber es dauert weniger als eine Sekunde, um das zu tun, was es tut:
NamesDefaultToHere(1);
dt = DataTable("Original");
// Find and select all the rows for a cancelled transaction
dt << selectWhere(startsWith(:InvoiceNo, "C"));
// Put these transactions into another table
dt2 = dt << Subset(SelectedRows(1), Columns(:Stock Code, :Customer ID, :UnitPrice));
dt2 << setName("Cancelled");
// Delete the cancelled transactions in dt
dt << deleteRows;
// Join dt2 to dt
dt3 = dt << Join(
With( dt2 ),
By Matching Columns(
:StockCode = :StockCode,
:CustomerID = :CustomerID,
:UnitPrice = :UnitPrice
),
Drop multiples( 0, 0 ),
Include Nonmatches( 1, 0 ),
Preserve main table order( 1 ),
OutputTableName("Work with Me")
);
Close(dt, NoSave);
Close(dt2, NoSave);
Re: Subtrahieren von Werten in Abhängigkeit von einer Variablen, die mit 'c beginnt, von einem TransaktionsdatensatzNachfolgend finden Sie ein Skript, das die UnBooking-Datensätze übernimmt und deren UnBooking-Menge aus dem vorherigen Buchungssatz für den angegebenen StockCode entfernt. Dann wird die UnBooking-Menge auf Null gesetzt. Wenn kein vorheriger Buchungssatz gefunden wird, wird davon ausgegangen, dass der Datensatz vor dem Start dieser Datentabelle vorhanden war, und die Menge des UnBooking-Pakets wird auf Null gesetzt.
Das Problem bei diesem Skript ist, dass es nicht sehr effizient ist. Bei den über 54.000 Aufnahmen hat es 55 Minuten gedauert. Andere Methoden könnten verwendet werden, um die Geschwindigkeit zu erhöhen, aber ich bemühte mich, etwas zu entwickeln, das Ihrer implizierten Methodik folgte.
Das Skript ist auch unvollständig im Umgang mit der Datenabstimmung. Das heißt, wenn die UnBooking-Menge 10 ist (in Ihren Daten -10) und die vorherige Buchungsmenge 7 ist, verwendet das Skript nicht die drei nicht abgebildeten Produkte und fährt rückwärts fort, um den nächsten Buchungssatz zu finden, und zieht die 3 nicht abgebildeten Produkte ab von dieser Buchung. Dies könnte hinzugefügt werden, wenn Sie sich für die Implementierung meiner Methode entscheiden.
Names Default To Here( 1 );
dt = Current Data Table();
// Record the starting time to allow the reporting of the amount of time it takes to
// perform all of the calculations
start = Today();
// Create a new column that represents the row number in the data table
dt << New Column( "RowNum", formula( Row() ) );
dt:RowNum << delete Property( "Formula" );
// Find all of the observations in the data table that are UnBookings
UnBookList = dt << get rows where( Uppercase( Left( :InvoiceNo, 1 ) ) == "C" & :Quantity < 0 );
// Loop across all of the UnBookings and subtract the UnBooking quantity from the
// Booking order record
For( corrections = 1, corrections <= N Rows( UnBookList ), corrections++,
// Print out the processing progress
If( Mod( corrections, 100 ) == 0,
time = Format( Today() - start, "hr:m:s" );
Show( time );
);
// Get the values of specific values for the current row being processed
curRowNum = UnBookList[corrections];
curCustomerID = dt:CustomerID[curRowNum];
curStockCode = dt:StockCode[curRowNum];
// Find the last row from the CustomerID's order for the StockCode being UnBooked
last row = Max( dt << get rows where( :quantity > 0 & curCustomerID == :CustomerID & curStockCode == :StockCode & :RowNum < curRowNum ) );
// If the record was found, then subtract (Sum the negative quantity) from the ordered quantity.
// Also, set the current rows quantity to zero
If( Is Missing( Last row ) == 0,
dt:Quantity[Last row] = Sum( dt:Quantity[Last row], dt:Quantity[curRowNum] );
);
// Set the current row's quantity value to zero
dt:Quantity[curRowNum] = 0;
);
// Print out the results
Show( N Rows( dt << get rows where( :quantity < 0 & Uppercase( Left( :InvoiceNo, 1 ) ) == "C" ) ) );
// Show the time it took to process the file
time = Format( Today() - start, "hr:m:s" );
Show( time );
// Delete the utility column RowNum
dt << Delete Columns( "RowNum" );
Re: Subtrahieren von Werten in Abhängigkeit von einer Variablen, die mit 'c beginnt, von einem TransaktionsdatensatzHallo Alexllorens!
Ist das etwas, was du einmal machst, oder etwas, das du wiederholt machst? Ich gehe davon aus, dass die Antwort "wiederholt" ist. Wenn ja, sollten Sie ein JSL-Skript schreiben.
Kann ein Kunde weniger als eine vollständige Bestellung zurücksenden? Mit anderen Worten: Wenn ein Kunde 50 Einheiten bestellt und 49 zurückgegeben hat, möchten Sie den Restbetrag in Ihre Buchhaltung aufnehmen?